搜尋

首頁  >  問答  >  主體

android线程访问网络报错

我在写一个欢迎界面的时候,报了下面的错误,感觉很奇怪。明明是在线程中访问了网络,怎么还会报这个错误

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中文网PHP中文网2772 天前609

全部回覆(3)我來回復

  • PHP中文网

    PHP中文网2017-04-17 13:33:42

    在4.0之後,網路操作不可以放在主線程,必須非同步操作,避免造成介面阻塞。
    介於你是使用Handler來執行網路操作,給出以下的解決方法:

    javaHandlerThread 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

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:33:42

    這個問題是從Android 4.0 開始出現,目的是將耗時的網路操作移除主線程,增加應用程式的及時回應,不阻塞使用者互動。解決想法就是將網路請求放入非同步執行緒處理,具體可以參考這篇文章囉嗦android中的NetworkOnMainThreadException

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:33:42

    你的程式碼沒有開任何一個新執行緒

      Handler handler = new Handler();
        //延迟一秒后进行
        handler.postDelayed(new AskServerIP(), 1000);
    

    你的Handler是在主執行緒中創建的,使用無參構造方法時,Handler會被綁定到創建Handler的執行緒上。

    然後你post了一個Runnable到Handler綁定的執行緒上執行.

    所以實際上AskServerIP最終是在主執行緒上執行的。

    回覆
    0
  • 取消回覆