Question

My App crashes on startup

1.If I Remove the Uses-sdk Tag from the Manifest.The app runs Perfect.

2.If I have Uses-sdk Tag in Manifest.It shows NetworkOnMainThreadException in the Log Cat.

I Used AsyncTask to Troubleshoot This ???

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)

MANIFEST

<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;
}

}

Was it helpful?

Solution

You have an exception and logging it like

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

or

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

does not work. Change the log message to something that is not empty "" or potentially null as e.getMessage(), for example, e.toString(). After that you can see the reason for what caused the exception you're trying to log.

If I had to guess, I'd say it's NetworkOnMainThreadException i.e. you're doing network ops such as InetAddress.getByName() on the main UI thread and the target SDK is 11 or higher. Why it work without the uses-sdk is that if unspecified, targetSdkVersion defaults to 1 with all the compatibility modes enabled.

For the canonical question about NetworkOnMainThreadException, see How to fix android.os.NetworkOnMainThreadException?

But it can be so many other things causing the primary exception as well. Fix the logging first.


After you've added the AsyncTask to offload network operations to a background thread, you'll need to make sure the UI operations are on the UI thread. This is what causes the

ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

AsyncTask's onPreExecute() and onPostExecute() run on the UI thread. That's the easiest way. You can also use Activity runOnUiThread() or a Handler to post Runnables to the UI thread.

OTHER TIPS

Try adding uses-permission to your manifest. You should put them right above your block.

The relevant ones for your code should be at least the following two:

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

You may want to add other permissions as well.

The relevant exception, once you've fixed your trivial Log.e error, should be the following one:

com.arul.remoteit.wifi.WifiApManager.getClientList(WifiApManager.java:147)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top