突然得到android.os.NetworkOnMainThreadException

时间:2013-07-27 10:54:55

标签: android

我有一个小应用程序,我已经工作了几个月,但突然我得到了

android.os.NetworkOnMainThreadException

我没有更改任何代码,这是崩溃的行

try {   
    endPoint = InetAddress.getByName(target.getToIp());
    port = target.getPort();
    socket = new DatagramSocket();
}
catch(Exception e) {
}

请注意,我没有发送任何我只是创建实例的内容,它已经在InetAddress行中中断了。

它在昨晚一直播放,我在手机上所做的就是在Google Play上运行更新,它更新到最新版本的谷歌地图,但是它不能有任何东西吗?

它在模拟器中工作,只有我的HTC One X断开

此处为完整代码 https://github.com/AndersMalmgren/FreePIE/tree/master/Lib/Android/FreePIE%20Android%20IMU

编辑: 清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.freepie.android.imu"
    android:versionCode="1"
    android:versionName="1.0">  

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.INTERNET" /> 

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" 
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity> 
    </application>

</manifest>

尝试将问题代码移到线程上,现在它不会中断,但套接字设置为null。

running = true;
worker = new Thread(new Runnable() { 
    public void run(){
        try {   
            endPoint = InetAddress.getByName(target.getToIp());
            port = target.getPort();
            socket = new DatagramSocket();
        }
        catch(Exception e) {
            Exception err = e;
        }

        while(running) {
            try {
            sync.await();
            } catch(Exception e) {}

            Send();
        }
        try  {
            socket.disconnect();
        }
        catch(Exception e)  {}
    }
}); 
worker.start();

更新 解决方案是在用户键入DNS而不是IP时添加一些故障回复 https://github.com/AndersMalmgren/FreePIE/commit/e8017e02a7893d9df41e4ed67a037f016b6a7d39

3 个答案:

答案 0 :(得分:5)

如果您尝试在主应用程序线程上执行网络I / O,默认情况下,您将在Android 4.0+上获得NetworkOnMainThreadException。如果您提供域名(而不是点IP表示法),getByName()会进行DNS查找,这会触发NetworkOnMainThreadException

答案 1 :(得分:1)

您必须将代码放在AsyncTask中,如下所示:

new AsyncTask<Void,Void,Void>(){
doInBackground(){
  endPoint = InetAddress.getByName(target.getToIp());
    port = target.getPort();
    socket = new DatagramSocket();
}
}.execute();

请注意,此代码不起作用,请详细了解AsyncTasks here

答案 2 :(得分:0)

Android 4.0不允许在主线程上使用网络。如果您在Android 2.3或其他版本上运行代码,则不会抛出任何异常。