我在写一个欢迎界面的时候,报了下面的错误,感觉很奇怪。明明是在线程中访问了网络,怎么还会报这个错误
05-22 21:42:32.855 15254-15254/com.zhu.teacherhelper E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.zhu.teacherhelper, PID: 15254
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:276)
at libcore.io.IoBridge.sendto(IoBridge.java:513)
at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184)
at java.net.DatagramSocket.send(DatagramSocket.java:305)
at com.zhu.teacherhelper.utils.ServerAddressUtils.AskServerAddress(ServerAddressUtils.java:39)
at com.zhu.teacherhelper.ui.WelcomeActivity$AskServerIP.run(WelcomeActivity.java:31)
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:5233)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
Handler handler = new Handler();
//延迟一秒后进行
handler.postDelayed(new AskServerIP(), 1000);
}
class AskServerIP implements Runnable{
@Override
public void run() {
//获取服务器ip地址
ServerAddressUtils.AskServerAddress(getApplicationContext());
Intent intent = new Intent(WelcomeActivity.this,MouseActivity.class);
startActivity(intent);
WelcomeActivity.this.finish();
}
}
PHP中文网2017-04-17 13:33:42
在4.0之後,網路操作不可以放在主線程,必須非同步操作,避免造成介面阻塞。
介於你是使用Handler來執行網路操作,給出以下的解決方法:
java
HandlerThread thread = new HandlerThread("NetWork"); thread.start(); Handler handler = new Handler(thread.getLooper()); //延迟一秒后进行 handler.postDelayed(new AskServerIP(), 1000);
改成這樣就行了。
要注意一個點:不是Handler就是非同步線程,Handler最關鍵的就是它的looper,如果在構建的時候沒傳looper進去,那麼默認使用構建Handler所在線程的looper。
你建構looper的地方在onCreate方法裡,也就是主線程,所以報錯。
關於這方面的知識,你可以在去搜尋以下。
慕課網路上有相關的教學課程,可以看以下:http://www.imooc.com/learn/267
伊谢尔伦2017-04-17 13:33:42
這個問題是從Android 4.0 開始出現,目的是將耗時的網路操作移除主線程,增加應用程式的及時回應,不阻塞使用者互動。解決想法就是將網路請求放入非同步執行緒處理,具體可以參考這篇文章囉嗦android中的NetworkOnMainThreadException
天蓬老师2017-04-17 13:33:42
你的程式碼沒有開任何一個新執行緒
Handler handler = new Handler();
//延迟一秒后进行
handler.postDelayed(new AskServerIP(), 1000);
你的Handler是在主執行緒中創建的,使用無參構造方法時,Handler會被綁定到創建Handler的執行緒上。
然後你post了一個Runnable到Handler綁定的執行緒上執行.
所以實際上AskServerIP最終是在主執行緒上執行的。