由于NetworkOnMainThreadException或<uses-sdk> </uses-sdk>,应用程序在启动时崩溃

时间:2013-12-28 19:09:21

标签: android debugging android-asynctask android-manifest networkonmainthread

我的应用程序在启动时崩溃

1.如果我从Manifest中删除了Uses-sdk标签。该应用程序运行完美。

2.如果我在清单中有Uses-sdk标记。它会在Log Cat中显示NetworkOnMainThreadException。

我使用AsyncTask来排除故障???

logcat的

12-29 15:32:33.673: E/AndroidRuntime(26748): FATAL EXCEPTION: AsyncTask #1
12-29 15:32:33.673: E/AndroidRuntime(26748): Process: com.arul.remoteit, PID: 26748
12-29 15:32:33.673: E/AndroidRuntime(26748): java.lang.RuntimeException: An error occured while executing doInBackground()
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.os.AsyncTask$3.done(AsyncTask.java:300)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.lang.Thread.run(Thread.java:841)
12-29 15:32:33.673: E/AndroidRuntime(26748): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.View.requestLayout(View.java:16438)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.View.requestLayout(View.java:16438)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.View.requestLayout(View.java:16438)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.View.requestLayout(View.java:16438)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.view.View.requestLayout(View.java:16438)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.widget.TextView.checkForRelayout(TextView.java:6600)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.widget.TextView.setText(TextView.java:3813)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.widget.TextView.setText(TextView.java:3671)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.widget.TextView.setText(TextView.java:3646)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at com.arul.remoteit.connect$scan.doInBackground(connect.java:31)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at com.arul.remoteit.connect$scan.doInBackground(connect.java:1)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at android.os.AsyncTask$2.call(AsyncTask.java:288)
12-29 15:32:33.673: E/AndroidRuntime(26748):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)

清单                     

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17"  />

  <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.arul.remoteit.Splash"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
  <activity android:name="com.arul.remoteit.main"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="com.arul.remoteit.Main" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>   

  <!-- 3rd Activity -->
   <activity android:name="com.arul.remoteit.connect"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="com.arul.remoteit.CONNECT" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>  

connect.java

public class connect extends Activity{
WifiApManager wifiApManager;
TextView tv;
Button scan;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.connect);
    tv =(TextView) findViewById(R.id.iptv);
    wifiApManager = new WifiApManager(this);
   new scan().execute();
}
public class scan extends AsyncTask<String, Integer, TextView> {

    @Override
    protected TextView doInBackground(String... params) {
         ArrayList<ClientScanResult> clients = wifiApManager.getClientList(false);
            tv.setText("WifiApState: " + wifiApManager.getWifiApState() + "\n\n");
            tv.append("Clients: \n");
            for (ClientScanResult clientScanResult : clients) {
                tv.append("####################\n");
                tv.append("IpAddr: " + clientScanResult.getIpAddr() + "\n");
                tv.append("Device: " + clientScanResult.getDevice() + "\n");
                tv.append("HWAddr: " + clientScanResult.getHWAddr() + "\n");
                tv.append("isReachable: " + clientScanResult.isReachable()+ "\n");
            }
            return tv;
        }
    }
 }

WifiApManager

public class WifiApManager {
private final WifiManager mWifiManager;

public WifiApManager(Context context) {
    mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}

public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
    try {
        if (enabled) { // disable WiFi in any case
            mWifiManager.setWifiEnabled(false);
        }

        Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
        return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
    } catch (Exception e) {
        Log.e(this.getClass().toString(), "wifi", e);
        return false;
    }
}

public WIFI_AP_STATE getWifiApState() {
    try {
        Method method = mWifiManager.getClass().getMethod("getWifiApState");

        int tmp = ((Integer)method.invoke(mWifiManager));

        // Fix for Android 4
        if (tmp > 10) {
            tmp = tmp - 10;
        }

        return WIFI_AP_STATE.class.getEnumConstants()[tmp];
    } catch (Exception e) {
        Log.e(this.getClass().toString(), "wifi", e);
        return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
    }
}


public boolean isWifiApEnabled() {
    return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
}


public WifiConfiguration getWifiApConfiguration() {
    try {
        Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
        return (WifiConfiguration) method.invoke(mWifiManager);
    } catch (Exception e) {
        Log.e(this.getClass().toString(), "wifi", e);
        return null;
    }
}


public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
    try {
        Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
        return (Boolean) method.invoke(mWifiManager, wifiConfig);
    } catch (Exception e) {
        Log.e(this.getClass().toString(), "wifi", e);
        return false;
    }
}


public ArrayList<ClientScanResult> getClientList(boolean onlyReachables) {
    return getClientList(onlyReachables, 10);
}


public ArrayList<ClientScanResult> getClientList(boolean onlyReachables, int reachableTimeout) {
    BufferedReader br = null;
    ArrayList<ClientScanResult> result = null;

    try {
        result = new ArrayList<ClientScanResult>();
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null) {
            String[] splitted = line.split(" +");

            if ((splitted != null) && (splitted.length >= 4)) {
                // Basic sanity check
                String mac = splitted[3];

                if (mac.matches("..:..:..:..:..:..")) {
                    boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);

                    if (!onlyReachables || isReachable) {
                        result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));
                    }
                }
            }
        }
    } catch (Exception e) {
        Log.e(LOGTAG, e.toString());
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            Log.e(LOGTAG, e.toString());
        }
    }
return result;
}

}

2 个答案:

答案 0 :(得分:3)

您有一个例外,并将其记录为

Log.e(..., "", ...);

Log.e(..., e.getMessage());

不起作用。将日志消息更改为非空""或可能为e.getMessage()的空值,例如e.toString()。之后,您可以看到导致您尝试记录的异常的原因。

如果我不得不猜测,我会说它是NetworkOnMainThreadException,即您在主UI线程上执行InetAddress.getByName()等网络操作,目标SDK为11或更高。如果没有uses-sdk,它的工作原理是,如果未指定,targetSdkVersion默认为1,并启用所有兼容模式。

有关NetworkOnMainThreadException的规范问题,请参阅How to fix android.os.NetworkOnMainThreadException?

但它可能是导致主要异常的许多其他因素。首先修复日志记录。


在将AsyncTask添加到后台线程的卸载网络操作之后,您需要确保UI操作位于UI线程上。这是导致

的原因
ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
在UI线程上运行

AsyncTask的{​​{1}}和onPreExecute()。这是最简单的方法。您还可以使用onPostExecute() ActivityrunOnUiThread()Handler发布到UI线程。

答案 1 :(得分:0)

尝试向您的清单添加uses-permission。你应该把它们放在你的块上方。

您的代码的相关内容应至少为以下两个:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

您可能还想添加其他权限。

相关的异常,一旦你修复了一些简单的Log.e错误,应该是以下错误:

com.arul.remoteit.wifi.WifiApManager.getClientList(WifiApManager.java:147)