2013-01-02 12 views
5

dopo aver provato il mio nuovo servizio su Android ottengo questo:android.os.NetworkOnMainThreadException all'avvio del servizio su Android

credo sia qualcosa legato al file manifesto e le autorizzazioni, il servizio viene avviato dopo l'ultima attività, per aggiornare i dati sul server e recuperare i nuovi dati e risparmiare id su SQLite su Android:

anche qui il file manifesto:

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

il logcat:

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 [email protected] 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 

sto facendo qualcosa di sbagliato?

questo è anche il servizio:

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 
     } 


} 
+1

hai cercato di chiamare il servizio da operazione asincrona? dice anche rete sull'eccezione del thread principale, non ho abbastanza esperienza con i servizi – vodich

+1

Leggi attentamente [thread] [1]. Spero che questo risolva il tuo problema. [1]: http://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception –

+0

che cosa si sta facendo male è che si sta networking sul thread UI, come suggerisce l'errore. quello che stai facendo anche di sbagliato è che questa domanda è stata risolta migliaia di volte, ma hai cercato una risposta prima di fare la domanda. – njzk2

risposta

8

Questo accade perché si sta eseguendo un'operazione di rete sul thread principale e questo non è consentito su Android 3.0 e versioni successive. Anche se si trova in un servizio, i servizi vengono eseguiti sul thread dell'interfaccia utente a meno che non vengano avviati in modo specifico in un altro thread o creato un thread al suo interno.

È possibile risolvere questo problema eseguendo l'attività in un servizio fuori dal thread principale dell'interfaccia utente, utilizzando un Thread o un AsyncTask.

Provare a creare una nuova discussione in onStartCommand(), come suggerito da @CommonsWare.

+1

Sì, è necessario utilizzare un thread in background. No, la tua soluzione non funzionerà. La cosa che fa il lavoro deve avere il thread in background e, in questo caso, è il servizio. 'onStartCommand()' ha bisogno del thread (possibilmente convertendolo in un 'IntentService'). Stai semplicemente cercando di legare da un thread in background, che non avrà alcun impatto sul thread usato per 'onStartCommand()', che è il thread dell'applicazione principale. – CommonsWare

+0

@CommonsWare Grazie per la correzione. Ho modificato la risposta. –

+0

THX per questo suggerimento –

3

As per the documentation, anche se si utilizza un Service per eseguire le operazioni esecuzione prolungata, il Servizio stesso viene eseguito sul thread principale dell'applicazione. Quindi devi generare un nuovo thread per eseguire attività potenzialmente lunghe come l'accesso alla rete.

Android's StrictMode verifica effettivamente le operazioni di rete eseguite sul thread principale e genera uno NetworkOnMainThreadException.

1

Prova questo. How to fix android.os.NetworkOnMainThreadException?

Leggere attentamente questa discussione.

Spero che questo risolva il tuo problema.

+2

ho appena vissuto questo problema e risolto in questo modo \t 'nuova Handler(). Posta (new Runnable() { \t \t \t \t \t \t @Override \t \t \t pubblico void run() { \t getData(); \t \t \t} \t \t}); ' – nesimtunc

4

Crea funzione:

Thread thread = new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     ....... 
    } 
}); 

E chiamare da onStartCommand

thread.start(); 
Problemi correlati