我有一个intentservice,可以将数据从手机上传到我的服务器。只要网络连接可用,我就从广播接收器启动它。一切正常但是当我通过Android 4.0.3模拟器测试时,它给出了严格模式错误android.os.NetworkOnMainThreadException。这就像这个网络作业在主线程上,但据我所知,intentservice已经成为一个工作线程。我发现此链接http://code.google.com/p/android/issues/detail?id=23495表示将网络作业移至后台线程。工作线程不是后台线程吗?
编辑:这是我的广播接收器。
public void onReceive(Context context, Intent intent) {
final String UploadingItems = "paUploadingItems";
final String preferencesFileName = "paSettings";
SharedPreferences sharedPref;
String fileQueque;
if(isNetworkAvailable(context)){
sharedPref = context.getSharedPreferences(preferencesFileName,0);
fileQueque = sharedPref.getString(UploadingItems, "");
Log.d(TAG, "quque"+fileQueque);
if(fileQueque.length() > 0){
Intent intentUpdater = new Intent(context, updaterService.class);
intentUpdater.putExtra("processMode", 6);
intentUpdater.putExtra("fileq", fileQueque.toString());
context.startService(intentUpdater);
}
}
}
private boolean isNetworkAvailable(Context context){
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
Log.d(TAG, activeNetworkInfo.getTypeName());
return (activeNetworkInfo != null && activeNetworkInfo.isAvailable() && activeNetworkInfo.isConnected());
}
这是我在LogCat中看到的错误:
04-17 15:28:58.114: E/AndroidRuntime(574): FATAL EXCEPTION: main
04-17 15:28:58.114: E/AndroidRuntime(574): java.lang.RuntimeException: Unable to start receiver org.test.dairy.OnNetworkReceiver: android.os.NetworkOnMainThreadException
04-17 15:28:58.114: E/AndroidRuntime(574): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2126)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.app.ActivityThread.access$1500(ActivityThread.java:123)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1197)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.os.Handler.dispatchMessage(Handler.java:99)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.os.Looper.loop(Looper.java:137)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.app.ActivityThread.main(ActivityThread.java:4424)
04-17 15:28:58.114: E/AndroidRuntime(574): at java.lang.reflect.Method.invokeNative(Native Method)
04-17 15:28:58.114: E/AndroidRuntime(574): at java.lang.reflect.Method.invoke(Method.java:511)
04-17 15:28:58.114: E/AndroidRuntime(574): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-17 15:28:58.114: E/AndroidRuntime(574): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-17 15:28:58.114: E/AndroidRuntime(574): at dalvik.system.NativeStart.main(Native Method)
04-17 15:28:58.114: E/AndroidRuntime(574): Caused by: android.os.NetworkOnMainThreadException
04-17 15:28:58.114: E/AndroidRuntime(574): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
04-17 15:28:58.114: E/AndroidRuntime(574): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
04-17 15:28:58.114: E/AndroidRuntime(574): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
04-17 15:28:58.114: E/AndroidRuntime(574): at java.net.InetAddress.getAllByName(InetAddress.java:220)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-17 15:28:58.114: E/AndroidRuntime(574): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)
04-17 15:28:58.114: E/AndroidRuntime(574): at org.test.dairy.OnNetworkReceiver.transferData(OnNetworkReceiver.java:101)
04-17 15:28:58.114: E/AndroidRuntime(574): at org.test.dairy.OnNetworkReceiver.onReceive(OnNetworkReceiver.java:57)
04-17 15:28:58.114: E/AndroidRuntime(574): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2119)
04-17 15:28:58.114: E/AndroidRuntime(574): ... 10 more
答案 0 :(得分:2)
您的isNetworkAvailable()方法检查主UI线程上的网络I / O,Android认为阻塞。我只是在不检查Activity中的连接的情况下触发对IntentService的请求,并让IntentService抛出异常并在无法建立连接的情况下向Activity报告。
答案 1 :(得分:0)
将代码移动到IntentService中。广播接收器的onReceive方法在UI线程上运行,网络代码导致它崩溃。只需将意图重定向到IntentService就可以了。
这使得代码也更简单。接收者实际上并不打算做复杂的逻辑,他们将消息从系统重定向到您的应用程序。服务意味着在后台做繁重的工作。