使用 AsyncTask 从显示在 ListView 中的服务器下载图像时出错 (android.os.NetworkOnMainThreadException)
Error (android.os.NetworkOnMainThreadException) while downloading images from the server showing in ListView using AsyncTask
我在 Android 中使用 AsyncTask 从服务器下载图像并在 ListView 中显示时遇到了一些问题。
它向我显示在主线程 (UI) 中下载图像的错误,但我为此目的使用了 AsyncTask。
这是我的 MainActivity.java 代码。
public class MainActivity extends AppCompatActivity {
private String[] imageURLArray = new String[]{
"http://farm8.staticflickr.com/7315/9046944633_881f24c4fa_s.jpg",
"http://farm4.staticflickr.com/3777/9049174610_bf51be8a07_s.jpg",
"http://farm8.staticflickr.com/7324/9046946887_d96a28376c_s.jpg",
"http://farm3.staticflickr.com/2828/9046946983_923887b17d_s.jpg",
"http://farm4.staticflickr.com/3810/9046947167_3a51fffa0b_s.jpg",
"http://farm4.staticflickr.com/3773/9049175264_b0ea30fa75_s.jpg",
"http://farm4.staticflickr.com/3781/9046945893_f27db35c7e_s.jpg",
"http://farm6.staticflickr.com/5344/9049177018_4621cb63db_s.jpg",
"http://farm8.staticflickr.com/7307/9046947621_67e0394f7b_s.jpg",
"http://farm6.staticflickr.com/5457/9046948185_3be564ac10_s.jpg",
"http://farm4.staticflickr.com/3752/9046946459_a41fbfe614_s.jpg",
"http://farm8.staticflickr.com/7403/9046946715_85f13b91e5_s.jpg",
"http://farm8.staticflickr.com/7315/9046944633_881f24c4fa_s.jpg",
"http://farm4.staticflickr.com/3777/9049174610_bf51be8a07_s.jpg",
"http://farm8.staticflickr.com/7324/9046946887_d96a28376c_s.jpg",
"http://farm3.staticflickr.com/2828/9046946983_923887b17d_s.jpg",
"http://farm4.staticflickr.com/3810/9046947167_3a51fffa0b_s.jpg",
"http://farm4.staticflickr.com/3773/9049175264_b0ea30fa75_s.jpg",
"http://farm4.staticflickr.com/3781/9046945893_f27db35c7e_s.jpg",
"http://farm6.staticflickr.com/5344/9049177018_4621cb63db_s.jpg",
"http://farm8.staticflickr.com/7307/9046947621_67e0394f7b_s.jpg",
"http://farm6.staticflickr.com/5457/9046948185_3be564ac10_s.jpg",
"http://farm4.staticflickr.com/3752/9046946459_a41fbfe614_s.jpg",
"http://farm8.staticflickr.com/7403/9046946715_85f13b91e5_s.jpg"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)this.findViewById(R.id.listView);
ImageAdapter imageAdapter = new ImageAdapter(this, R.layout.imageitem, imageURLArray);
listView.setAdapter(imageAdapter);
}
}
这是我的 ImageAdapter.java 代码。
public class ImageAdapter extends ArrayAdapter<String> {
private String[] imageURLArray;
private LayoutInflater inflater;
public ImageAdapter(Context context, int textViewResourceId,
String[] imageArray) {
super(context, textViewResourceId, imageArray);
// TODO Auto-generated constructor stub
inflater = ((Activity) context).getLayoutInflater();
imageURLArray = imageArray;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.imageitem, null);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.testImage);
convertView.setTag(viewHolder);
}
viewHolder = (ViewHolder) convertView.getTag();
Bitmap imageBitmap = null;
try {
URL imageURL = new URL(imageURLArray[position]);
imageBitmap = BitmapFactory.decodeStream(imageURL.openStream());
viewHolder.imageView.setImageBitmap(imageBitmap);
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
}
return convertView;
}
private static class ViewHolder {
Bitmap bitmap;
String imageURL;
ImageView imageView;
}
private class DownloadAsyncTask extends AsyncTask<ViewHolder, Void, ViewHolder> {
@Override
protected ViewHolder doInBackground(ViewHolder... params) {
// TODO Auto-generated method stub
//load image directly
ViewHolder viewHolder = params[0];
try {
URL imageURL = new URL(viewHolder.imageURL);
viewHolder.bitmap = BitmapFactory.decodeStream(imageURL.openStream());
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.bitmap = null;
}
return viewHolder;
}
@Override
protected void onPostExecute(ViewHolder result) {
if (result.bitmap == null) {
result.imageView.setImageResource(R.mipmap.ic_launcher);
} else {
result.imageView.setImageBitmap(result.bitmap);
}
}
}
}
这是具有完整项目的 link。
http://www.mediafire.com/download/70pxv6ib584x9j7/DownloadImagesInListView.rar
这是显示的错误堆栈。
09-29 18:33:37.859 5550-5550/com.example.android.downloadimagesinlistview E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.android.downloadimagesinlistview, PID: 5550
android.os.NetworkOnMainThreadException
at
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1161)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.HostResolver.getAllByName(HostResolver.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
at java.net.URL.openStream(URL.java:470)
at com.example.android.downloadimagesinlistview.ImageAdapter.getView(ImageAdapter.java:48)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillFromTop(ListView.java:759)
at android.widget.ListView.layoutChildren(ListView.java:1673)
at android.widget.AbsListView.onLayout(AbsListView.java:2151)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2116)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1873)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1084)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5990)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(
当您在主线程上执行网络相关操作时会出现此异常。要下载图像,您必须在 AsyncTask 中执行操作或使用 picasso 库。
使用 Picasso 使用这个
Picasso.with(MainActivity.this).load(imageURLArray[position]).error(R.mipmap.ic_launcher).into(viewHolder.imageView);
在
的地方
Bitmap imageBitmap = null;
try {
URL imageURL = new URL(imageURLArray[position]);
imageBitmap = BitmapFactory.decodeStream(imageURL.openStream());
viewHolder.imageView.setImageBitmap(imageBitmap);
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
}
我在 Android 中使用 AsyncTask 从服务器下载图像并在 ListView 中显示时遇到了一些问题。
它向我显示在主线程 (UI) 中下载图像的错误,但我为此目的使用了 AsyncTask。
这是我的 MainActivity.java 代码。
public class MainActivity extends AppCompatActivity {
private String[] imageURLArray = new String[]{
"http://farm8.staticflickr.com/7315/9046944633_881f24c4fa_s.jpg",
"http://farm4.staticflickr.com/3777/9049174610_bf51be8a07_s.jpg",
"http://farm8.staticflickr.com/7324/9046946887_d96a28376c_s.jpg",
"http://farm3.staticflickr.com/2828/9046946983_923887b17d_s.jpg",
"http://farm4.staticflickr.com/3810/9046947167_3a51fffa0b_s.jpg",
"http://farm4.staticflickr.com/3773/9049175264_b0ea30fa75_s.jpg",
"http://farm4.staticflickr.com/3781/9046945893_f27db35c7e_s.jpg",
"http://farm6.staticflickr.com/5344/9049177018_4621cb63db_s.jpg",
"http://farm8.staticflickr.com/7307/9046947621_67e0394f7b_s.jpg",
"http://farm6.staticflickr.com/5457/9046948185_3be564ac10_s.jpg",
"http://farm4.staticflickr.com/3752/9046946459_a41fbfe614_s.jpg",
"http://farm8.staticflickr.com/7403/9046946715_85f13b91e5_s.jpg",
"http://farm8.staticflickr.com/7315/9046944633_881f24c4fa_s.jpg",
"http://farm4.staticflickr.com/3777/9049174610_bf51be8a07_s.jpg",
"http://farm8.staticflickr.com/7324/9046946887_d96a28376c_s.jpg",
"http://farm3.staticflickr.com/2828/9046946983_923887b17d_s.jpg",
"http://farm4.staticflickr.com/3810/9046947167_3a51fffa0b_s.jpg",
"http://farm4.staticflickr.com/3773/9049175264_b0ea30fa75_s.jpg",
"http://farm4.staticflickr.com/3781/9046945893_f27db35c7e_s.jpg",
"http://farm6.staticflickr.com/5344/9049177018_4621cb63db_s.jpg",
"http://farm8.staticflickr.com/7307/9046947621_67e0394f7b_s.jpg",
"http://farm6.staticflickr.com/5457/9046948185_3be564ac10_s.jpg",
"http://farm4.staticflickr.com/3752/9046946459_a41fbfe614_s.jpg",
"http://farm8.staticflickr.com/7403/9046946715_85f13b91e5_s.jpg"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)this.findViewById(R.id.listView);
ImageAdapter imageAdapter = new ImageAdapter(this, R.layout.imageitem, imageURLArray);
listView.setAdapter(imageAdapter);
}
}
这是我的 ImageAdapter.java 代码。
public class ImageAdapter extends ArrayAdapter<String> {
private String[] imageURLArray;
private LayoutInflater inflater;
public ImageAdapter(Context context, int textViewResourceId,
String[] imageArray) {
super(context, textViewResourceId, imageArray);
// TODO Auto-generated constructor stub
inflater = ((Activity) context).getLayoutInflater();
imageURLArray = imageArray;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.imageitem, null);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.testImage);
convertView.setTag(viewHolder);
}
viewHolder = (ViewHolder) convertView.getTag();
Bitmap imageBitmap = null;
try {
URL imageURL = new URL(imageURLArray[position]);
imageBitmap = BitmapFactory.decodeStream(imageURL.openStream());
viewHolder.imageView.setImageBitmap(imageBitmap);
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
}
return convertView;
}
private static class ViewHolder {
Bitmap bitmap;
String imageURL;
ImageView imageView;
}
private class DownloadAsyncTask extends AsyncTask<ViewHolder, Void, ViewHolder> {
@Override
protected ViewHolder doInBackground(ViewHolder... params) {
// TODO Auto-generated method stub
//load image directly
ViewHolder viewHolder = params[0];
try {
URL imageURL = new URL(viewHolder.imageURL);
viewHolder.bitmap = BitmapFactory.decodeStream(imageURL.openStream());
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.bitmap = null;
}
return viewHolder;
}
@Override
protected void onPostExecute(ViewHolder result) {
if (result.bitmap == null) {
result.imageView.setImageResource(R.mipmap.ic_launcher);
} else {
result.imageView.setImageBitmap(result.bitmap);
}
}
}
}
这是具有完整项目的 link。
http://www.mediafire.com/download/70pxv6ib584x9j7/DownloadImagesInListView.rar
这是显示的错误堆栈。
09-29 18:33:37.859 5550-5550/com.example.android.downloadimagesinlistview E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.android.downloadimagesinlistview, PID: 5550
android.os.NetworkOnMainThreadException
at
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1161)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.HostResolver.getAllByName(HostResolver.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
at java.net.URL.openStream(URL.java:470)
at com.example.android.downloadimagesinlistview.ImageAdapter.getView(ImageAdapter.java:48)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillFromTop(ListView.java:759)
at android.widget.ListView.layoutChildren(ListView.java:1673)
at android.widget.AbsListView.onLayout(AbsListView.java:2151)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2116)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1873)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1084)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5990)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(
当您在主线程上执行网络相关操作时会出现此异常。要下载图像,您必须在 AsyncTask 中执行操作或使用 picasso 库。
使用 Picasso 使用这个
Picasso.with(MainActivity.this).load(imageURLArray[position]).error(R.mipmap.ic_launcher).into(viewHolder.imageView);
在
的地方Bitmap imageBitmap = null;
try {
URL imageURL = new URL(imageURLArray[position]);
imageBitmap = BitmapFactory.decodeStream(imageURL.openStream());
viewHolder.imageView.setImageBitmap(imageBitmap);
} catch (IOException e) {
// TODO: handle exception
Log.e("error", "Downloading Image Failed");
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
}