Android连接网络异常:android.os.NetworkOnMainThreadException
packagecom.ccl.getp_w_picpath;importjava.io.InputStream;importjava.net.HttpURLConnection;importjava.net.URL;importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.os.Bundle;importandroid.text.TextUtils;importandroid.view.View;importandroid.widget.EditText;importandroid.widget.ImageView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{privateEditTextet_path;privateImageViewiv;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et_path=(EditText)findViewById(R.id.et_path);iv=(ImageView)findViewById(R.id.iv);}publicvoidgetImage(Viewview){Stringpath=et_path.getText().toString().trim();if(TextUtils.isEmpty(path)){Toast.makeText(this,"地址不能为空",0).show();return;}try{URLurl=newURL(path);HttpURLConnectionconn=(HttpURLConnection)url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);System.out.println("响应码是--"+conn.getResponseCode());if(conn.getResponseCode()==200){//获取服务器返回的流数据InputStreamin=conn.getInputStream();//将返回的流数据解析成图片Bitmapbitmap=BitmapFactory.decodeStream(in);//显示图片iv.setImageBitmap(bitmap);in.close();}}catch(Exceptione){e.printStackTrace();}}}
Android模拟器版本4.1.2
异常解释:在主线程中的网络异常
原因:Android2.3版本后不允许在主线程中直接请求网络获取数据
解决方法(两种):
一:onCreate方法中加入如下代码(不推荐使用,有可能阻塞Android主线程)
if(android.os.Build.VERSION.SDK_INT>9){StrictMode.ThreadPolicypolicy=newStrictMode.ThreadPolicy.Builder().permitAll().build();StrictMode.setThreadPolicy(policy);}
二:使用Android 的handler机制,另外开启一个子线程请求网络获取数据(推荐使用)
packagecom.ccl.getp_w_picpath;importjava.io.InputStream;importjava.net.HttpURLConnection;importjava.net.URL;importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.text.TextUtils;importandroid.view.View;importandroid.widget.EditText;importandroid.widget.ImageView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{privateEditTextet_path;privateImageViewiv;privateStringpath;//使用Handler更新主线程(UI线程)privateHandlerhandler=newHandler(){publicvoidhandleMessage(Messagemsg){Bitmapbitmap=(Bitmap)msg.obj;iv.setImageBitmap(bitmap);};};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et_path=(EditText)findViewById(R.id.et_path);iv=(ImageView)findViewById(R.id.iv);}publicvoidgetImage(Viewview){path=et_path.getText().toString().trim();if(TextUtils.isEmpty(path)){Toast.makeText(this,"地址不能为空",0).show();return;}newThread(){publicvoidrun(){try{URLurl=newURL(path);HttpURLConnectionconn=(HttpURLConnection)url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);System.out.println("响应码是--"+conn.getResponseCode());if(conn.getResponseCode()==200){//获取服务器返回的流数据InputStreamin=conn.getInputStream();//将返回的流数据解析成图片Bitmapbitmap=BitmapFactory.decodeStream(in);//使用handler传递消息Messagemsg=Message.obtain();msg.obj=bitmap;//传递的数据handler.sendMessage(msg);in.close();}}catch(Exceptione){e.printStackTrace();}}}.start();}}
注意两点:
Message对象的创建使用obtain方法可以达到对象重用的目的,节省内存开销。
Message对象可以使用msg.what = 传递消息的类型,handler可以根据传递的消息类型做不同处理,优化代码如下:
packagecom.ccl.getp_w_picpath;importjava.io.InputStream;importjava.net.HttpURLConnection;importjava.net.URL;importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.text.TextUtils;importandroid.view.View;importandroid.widget.EditText;importandroid.widget.ImageView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{protectedstaticfinalintSUCCESS=0;protectedstaticfinalintERROR=1;protectedstaticfinalintNETWORK_ERROR=2;privateEditTextet_path;privateImageViewiv;privateStringpath;//使用Handler更新主线程(UI线程)privateHandlerhandler=newHandler(){publicvoidhandleMessage(Messagemsg){switch(msg.what){caseSUCCESS:Bitmapbitmap=(Bitmap)msg.obj;iv.setImageBitmap(bitmap);break;caseERROR:Toast.makeText(MainActivity.this,"获取图片失败",0).show();break;caseNETWORK_ERROR:Toast.makeText(MainActivity.this,"连接网络失败",0).show();break;}};};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et_path=(EditText)findViewById(R.id.et_path);iv=(ImageView)findViewById(R.id.iv);}publicvoidgetImage(Viewview){path=et_path.getText().toString().trim();if(TextUtils.isEmpty(path)){Toast.makeText(this,"地址不能为空",0).show();return;}newThread(){publicvoidrun(){try{URLurl=newURL(path);HttpURLConnectionconn=(HttpURLConnection)url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);System.out.println("响应码是--"+conn.getResponseCode());if(conn.getResponseCode()==200){//获取服务器返回的流数据InputStreamin=conn.getInputStream();//将返回的流数据解析成图片Bitmapbitmap=BitmapFactory.decodeStream(in);//使用handler传递消息Messagemsg=Message.obtain();msg.obj=bitmap;//传递的数据msg.what=SUCCESS;//传递的消息类型,handler可根据消息类型做不同处理handler.sendMessage(msg);in.close();}else{Messagemsg=Message.obtain();msg.what=ERROR;handler.sendMessage(msg);}}catch(Exceptione){Messagemsg=Message.obtain();msg.what=NETWORK_ERROR;handler.sendMessage(msg);e.printStackTrace();}}}.start();}}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。