android之android.os.NetworkOnMainThreadException异常

在MainActivity中加载网络图片,代码以下:
java

public class NetImageActivity extends Activity {

     String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.jpg";   
     Bitmap bmImg;
     ImageView imView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imView = (ImageView) findViewById(R.id.imageViewId);
        imView.setImageBitmap(returnBitMap(imageUrl));   
    } 
       
    public Bitmap returnBitMap(String url){ 
        URL myFileUrl = null;
        Bitmap bitmap = null;  
        try {   
            myFileUrl = new URL(url);   
        } catch (MalformedURLException e) {
            e.printStackTrace();   
        }   
        try {   
            HttpURLConnection conn = (HttpURLConnection) myFileUrl
              .openConnection();   
            conn.setDoInput(true);   
            conn.connect();   
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();   
        } catch (IOException e) {
              e.printStackTrace();   
        }   
              return bitmap;   
    }   
}

报错,信息以下
android

 Caused by: android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
            at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
            at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
            at java.net.InetAddress.getAllByName(InetAddress.java:214)
            at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
            at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
            at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
            at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
            at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
            at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
            at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
            at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)

    android.os.NetworkOnMainThreadException是说不要在主线程中访问网络,这个是android3.0版本开始就强制程序不能在主线程中访问网络,要把访问网络放在独立的线程中。网络

    在开发中,为了防止访问网络阻塞主线程,通常都要把访问网络放在独立线程中或者异步线程AsyncTask中。异步

一、想要忽略这些强制策略问题的话,能够在onCreate()方法里面加上ide

StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

 并在方法上加上@SuppressLint("NewApi"),重试,OK。ui

二、将网络访问放到单独线程中: url

public class NetImageActivity extends Activity {

    String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.jpg";
    Bitmap bitmap;
    ImageView imView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imView = (ImageView) findViewById(R.id.imageViewId);
        Thread imageViewHander = new Thread(new NetImageHandler());
        imageViewHander.start();
    }


    class NetImageHandler implements Runnable {
        @Override
        public void run() {
            try {
                URL url = new URL(imageUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true);
                conn.connect();
                InputStream is = conn.getInputStream();
                bitmap = BitmapFactory.decodeStream(is);
                //发送消息,通知UI组件显示图片
                handler.sendEmptyMessage(0);
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == 0){
                imView.setImageBitmap(bitmap);
            }
        }
    };

}

三、将网络访问放到异步任务AsyncTask中,代码以下: spa

public class NetImageActivity extends Activity {

    String imageUrl = "http://content.52pk.com/files/100623/2230_102437_1_lit.jpg";
    ImageView imView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imView = (ImageView) findViewById(R.id.imageViewId);
        loadImage();
    }

    private void loadImage() {
        new AsyncTask<String, Void, Bitmap>() {
            //该方法运行在后台线程中,所以不能在该线程中更新UI,UI线程为主线程
            @Override
            protected Bitmap doInBackground(String... params) {
                Bitmap bitmap = null;
                try {
                    String url = params[0];
                    URL HttpURL = new URL(url);
                    HttpURLConnection conn = (HttpURLConnection) HttpURL.openConnection();
                    conn.setDoInput(true);
                    conn.connect();
                    InputStream is = conn.getInputStream();
                    bitmap = BitmapFactory.decodeStream(is);
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bitmap;
            }

            //在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,
            // 后台的计算结果将经过该方法传递到UI线程,而且在界面上展现给用户.
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if(bitmap != null){
                    imView.setImageBitmap(bitmap);
                }
            }
        }.execute(imageUrl);
    }

}
相关文章
相关标签/搜索