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;
}
}
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 Runnable
s to the UI thread.