2013-01-02 10 views
5

po próbie mój nowy serwis na Android i uzyskać w ten sposób:android.os.NetworkOnMainThreadException na początku usług na Androidzie

Chyba jest coś związane z pliku manifestu i uprawnieniami, usługa jest uruchomiona po ostatniej aktywności, aktualizować dane na serwerze i pobierać nowe dane i zapisać identyfikator na SQLite na Androidzie:

tutaj również plik manifestu:

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

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 

Czy robię coś nie tak?

to również usługa:

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

pan spróbować wezwać serwis z zadania asynchroniczny? mówi również o sieci na głównym wątku wyjątku, nie mam wystarczającego doświadczenia z usługami – vodich

+1

Przeczytaj uważnie [wątek] [1]. Mam nadzieję, że rozwiąże to Twój problem. [1]: http://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception –

+0

co robisz źle, że jesteś w sieci na wątków UI, jak sugeruje błąd. to, co robisz źle, to to, że odpowiedź na to pytanie była tysiące razy, ale szukałeś odpowiedzi, zanim zadasz pytanie. – njzk2

Odpowiedz

8

Dzieje się tak, ponieważ wykonujesz operację sieciową na głównym wątku, co nie jest dozwolone w systemie Android 3.0 i nowszych wersjach. Mimo że jest to usługa, usługi są uruchamiane w wątku interfejsu użytkownika, chyba że użytkownik uruchomi je w innym wątku lub utworzy w nim wątek.

Możesz to naprawić, uruchamiając zadanie w usłudze wyłączonej z głównego wątku UI, używając Thread lub AsyncTask.

Spróbuj utworzyć nowy wątek w onStartCommand(), zgodnie z sugestią @CommonsWare.

+1

Tak, musisz użyć wątku tła. Nie, twoje rozwiązanie nie zadziała. Rzecz wykonująca pracę musi mieć wątek podstawowy, w tym przypadku jest to usługa. 'onStartCommand()' potrzebuje wątku (prawdopodobnie przez konwersję do 'IntentService'). Po prostu próbujesz powiązać wątek tła, który nie będzie miał wpływu na wątek używany do 'onStartCommand()', który jest głównym wątkiem aplikacji. – CommonsWare

+0

@CommonsWare Dziękujemy za poprawkę. Edytowałem odpowiedź. –

+0

THX dla tego nutą –

3

As per the documentation, chociaż użyć Service do wykonywania długich operacji działa, sama usługa działa na głównym wątku aplikacji. Musisz więc utworzyć nowy wątek, aby wykonywać potencjalnie długie zadania, takie jak dostęp do sieci.

Android StrictMode faktycznie sprawdza operacje sieciowe wykonywane na głównym wątku i generuje NetworkOnMainThreadException.

1

Spróbuj tego. How to fix android.os.NetworkOnMainThreadException?

Przeczytaj uważnie ten wątek.

Mam nadzieję, że rozwiąże to Twój problem.

+2

prostu żył i rozwiązać ten problem jak ten \t 'nowy Handler(). Pocztą (nowa Runnable() { \t \t \t \t \t \t @Override \t \t \t public void run() { \t getData(); \t \t \t} \t \t}); ' – nesimtunc

4

Tworzenie funkcji:

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

i wywołać ją z onStartCommand

thread.start();