android.os.NetworkOnMainThreadException 在 android 上启动服务 [英] android.os.NetworkOnMainThreadException on service start on android
问题描述
在 android 上尝试我的全新服务后,我得到了这个:
after trying my brand new service on android i get this:
我猜是一些与清单文件和权限有关的东西,该服务在最后一个活动之后启动,以更新服务器上的数据并检索新数据并将 id 保存在 android 上的 sqlite 上:
i guess is something related to the manifest file and permissions, the service is started after the last activity, to update data on server and retrieve new data and save id on sqlite on android:
这里还有清单文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ggservice.democracy"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.ggservice.democracy.MainActivity"
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:label="@string/app_name" android:name="com.ggservice.democracy.sondaggioActivity"/>
<activity android:label="@string/app_name" android:name="com.ggservice.democracy.domandeDiCategoria"/>
<service android:name="com.ggservice.democracy.updateDemocracyService" />
</application>
</manifest>
日志猫:
01-02 15:33:30.960: W/dalvikvm(2570): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
01-02 15:33:31.160: E/AndroidRuntime(2570): FATAL EXCEPTION: main
01-02 15:33:31.160: E/AndroidRuntime(2570): java.lang.RuntimeException: Unable to start service com.ggservice.democracy.updateDemocracyService@412f0c60 with Intent { cmp=com.ggservice.democracy/.updateDemocracyService }: android.os.NetworkOnMainThreadException
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2376)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.app.ActivityThread.access$1900(ActivityThread.java:123)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.os.Looper.loop(Looper.java:137)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-02 15:33:31.160: E/AndroidRuntime(2570): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 15:33:31.160: E/AndroidRuntime(2570): at java.lang.reflect.Method.invoke(Method.java:511)
01-02 15:33:31.160: E/AndroidRuntime(2570): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-02 15:33:31.160: E/AndroidRuntime(2570): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-02 15:33:31.160: E/AndroidRuntime(2570): at dalvik.system.NativeStart.main(Native Method)
01-02 15:33:31.160: E/AndroidRuntime(2570): Caused by: android.os.NetworkOnMainThreadException
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
01-02 15:33:31.160: E/AndroidRuntime(2570): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
01-02 15:33:31.160: E/AndroidRuntime(2570): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
01-02 15:33:31.160: E/AndroidRuntime(2570): at java.net.InetAddress.getAllByName(InetAddress.java:220)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-02 15:33:31.160: E/AndroidRuntime(2570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-02 15:33:31.160: E/AndroidRuntime(2570): at com.ggservice.democracy.JSONParser.getJSONFromUrl(JSONParser.java:38)
01-02 15:33:31.160: E/AndroidRuntime(2570): at com.ggservice.democracy.updateDemocracyService.onStartCommand(updateDemocracyService.java:47)
01-02 15:33:31.160: E/AndroidRuntime(2570): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2359)
01-02 15:33:31.160: E/AndroidRuntime(2570): ... 10 more
我做错了吗?
这也是服务:
public class updateDemocracyService extends Service{
private pollDataSource datasource;
int mStartMode; // indicates how to behave if the service is killed
IBinder mBinder; // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used
// url to make request
private static String url = "http://www.test.com/democracy/domande.php";
// JSON Node names
private static final String TAG_DOMANDE = "domande";
private static final String TAG_ID = "id";
private static final String TAG_TESTO = "testo";
// contacts JSONArray
JSONArray contacts = null;
@Override
public void onCreate() {
// The service is being created
datasource = new pollDataSource(this);
datasource.open();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_DOMANDE);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_TESTO);
datasource.createCategoria(name);
}
} catch (JSONException e) {
e.printStackTrace();
}
Toast.makeText(this, "ho comunicato con un server!", Toast.LENGTH_LONG).show();
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
@Override
public void onDestroy() {
datasource.close();
// The service is no longer used and is being destroyed
}
}
推荐答案
出现这种情况是因为你在主线程上进行网络操作,Android 3.0及以上是不允许的.即使它在一个服务中,服务也会在 UI 线程上运行,除非您专门在另一个线程中启动它们或在其中创建一个线程.
This happens because you are doing a network operation on the main thread, and this is not allowed on Android 3.0 and above. Even though it is in a service, services are run on the UI thread unless you specifically launch them in another thread or create a thread inside it.
您可以通过使用 线程在主 UI 线程之外的服务中运行任务来解决此问题 或 AsyncTask.
You can fix this by running the task in a service off the main UI thread, by using a Thread or an AsyncTask.
按照@CommonsWare 的建议,尝试在 onStartCommand()
中创建一个新线程.
Try creating a new thread in onStartCommand()
, as suggested by @CommonsWare.
这篇关于android.os.NetworkOnMainThreadException 在 android 上启动服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!