在 NetworkOnMainThreadException 中将 url 转换为位图 [重复]
Posted
技术标签:
【中文标题】在 NetworkOnMainThreadException 中将 url 转换为位图 [重复]【英文标题】:Convert url to bitmap in NetworkOnMainThreadException [duplicate] 【发布时间】:2016-05-19 00:39:22 【问题描述】:我想将来自某些 URLS 的图像动态添加到线性布局中。运行这段代码时出现错误无法启动活动
ComponentInfo: android.os.NetworkOnMainThreadException 在 com.example.star.example.CompinfoActivity.getBitmapFromURL(CompinfoActivity.java:70) 在 com.example.star.example.CompinfoActivity.insertPhoto(CompinfoActivity.java:50) 在 com.example.star.example.CompinfoActivity.onCreate(CompinfoActivity.java:38)
请帮忙。这是我下面活动的代码。
public class CompinfoActivity extends AppCompatActivity
Dialog dialog;
LinearLayout myGallery;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compinfo);
dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.activity_compinfopopup);
dialog.getWindow().getAttributes().width = AbsListView.LayoutParams.MATCH_PARENT;
dialog.getWindow().getAttributes().height = AbsListView.LayoutParams.WRAP_CONTENT;
dialog.show();
myGallery = (LinearLayout) dialog.findViewById(R.id.mygallery);
myGallery.addView(insertPhoto("http://example.com/a.png"));
myGallery.addView(insertPhoto("http://example.com/b.png"));
myGallery.addView(insertPhoto("http://example.com/c.png"));
myGallery.addView(insertPhoto("http://example.com/d.png"));
new MyTask().execute();
View insertPhoto(String path)
Bitmap bm;
bm = getBitmapFromURL(path);
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
layout.setGravity(Gravity.CENTER);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(bm);
layout.addView(imageView);
return layout;
public static Bitmap getBitmapFromURL(String src)
try
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
catch (IOException e)
e.printStackTrace();
return null;
【问题讨论】:
你应该在 bcakground 线程中定义你的获取位图代码或使用异步任务 【参考方案1】:只需执行以下操作 -
public class MyAsync extends AsyncTask<Void, Void, Bitmap>
@Override
protected Bitmap doInBackground(Void... params)
try
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
catch (IOException e)
e.printStackTrace();
return null;
现在要从 url 访问位图,请执行以下操作 -
MyAsync obj = new MyAsync()
@Override
protected void onPostExecute(Bitmap bmp)
super.onPostExecute(bmp);
Bitmap bm = bmp;
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
layout.setGravity(Gravity.CENTER);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(bm);
layout.addView(imageView);
;
然后最后执行 AsynTask -
obj.execute();
【讨论】:
@Ashish:很高兴它对你有所帮助 :) 请点赞。【参考方案2】:在android中调用此方法将Url转换为Bitmap
public static Bitmap getBitmapFromURL(String url)
try
URL url = new URL(url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmapFrmUrl = BitmapFactory.decodeStream(input);
return bitmapFrmUrl;
catch (IOException e)
e.printStackTrace();
return null;
不要忘记在 AndroidManifest.xml 中添加 INTERNET 权限
【讨论】:
【参考方案3】:试试这个
URL url = new URL("http://....");
Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
只需替换您的网址即可为我工作
【讨论】:
android.os.NetworkOnMainThreadException【参考方案4】:您不应该像 ankit 所说的那样在主线程中进行任何网络调用。您在 OnCreate() 方法中编写了所有内容。请改用AsyncTask。
我建议你使用凌空NetworkImageView 或Universal Image loader。
直接从服务器显示图像。
【讨论】:
【参考方案5】:您不能在 UI 主线程上进行任何网络调用。像下面这样实现 AsyncTask 并调用
new LoadImage(imageView).execute()
异步任务实现::
class LoadImage extends AsyncTask<Object, Void, Bitmap>
private ImageView imv;
private String path;
public LoadImage(ImageView imv)
this.imv = imv;
this.path = imv.getTag().toString();
@Override
protected Bitmap doInBackground(Object... params)
Bitmap bitmap = null;
File file = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + path);
if(file.exists())
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
return bitmap;
@Override
protected void onPostExecute(Bitmap result)
if (!imv.getTag().toString().equals(path))
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
if(result != null && imv != null)
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
【讨论】:
【参考方案6】:在应用程序中显示图片,将它们下载到存储中,然后显示它们的作品
您将通过搜索如何下载文件、编写 OnDownloadCompleteListener 来得到答案
并在每次下载图片时重新加载您的 imageView。
【讨论】:
【参考方案7】:更改您的 insertPhoto(String path) 方法如下:
View insertPhoto(String path)
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
layout.setGravity(Gravity.CENTER);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
//Download and display image
new AsyncTask<String, Void, Bitmap>()
@Override
protected Bitmap doInBackground(String... urls)
String url = urls[0];
Bitmap mIcon11 = null;
try
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
mIcon11 = BitmapFactory.decodeStream(input);
catch (Exception e)
Log.e("Error for image ", e.getMessage());
e.printStackTrace();
mIcon11 = null;
return mIcon11;
protected void onPostExecute(Bitmap result)
if(result!= null)
imageView.setImageBitmap(null);
imageView.setImageBitmap(result);
.execute(path);
layout.addView(imageView);
return layout;
希望这会有所帮助。
【讨论】:
以上是关于在 NetworkOnMainThreadException 中将 url 转换为位图 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?