使用 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);
}