android之android.os.NetworkOnMainThreadException异常

来源:互联网 发布:南通java培训班 编辑:程序博客网 时间:2024/06/08 10:23

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

public class NetImageActivity extends Activity {     String imageUrl = "http://s0.hao123img.com/res/img/moe/0328mh5.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;       }   }

报错,信息如下

 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中。

1、想要忽略这些强制策略问题的话,可以在onCreate()方法里面加上

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

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

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

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

3、将网络访问放到异步任务AsyncTask中,代码如下:

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


0 0