我的应用程序在启动时崩溃
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;
}
}
答案 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()
Activity
或runOnUiThread()
将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)