2016-08-17 1 views
1

Ich verwende Service, um den Serverstatus zu überprüfen und Benutzer darüber zu informieren. Es funktioniert gut, bis die Aktivität der App zerstört wurde. Ich behalte den Dienst auch wenn die Aktivität zerstört wird, aber wenn jedes Mal fehlschlägt. Irgendwelche Vorschläge?Warum wirft es android.os.NetworkOnMainThreadException auf Dienst nach Aktivität zerstört?

Service:

package com.vasil.wall.chss.MP; 

import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.os.IBinder; 
import android.os.Binder; 
import android.os.Handler; 
import android.support.v4.app.NotificationCompat; 

import android.os.Handler; 
import java.util.TimerTask; 
import java.util.Timer; 
import org.peter.cucker.Single; 

import android.util.Log; 
import android.os.AsyncTask; 

import com.vasil.wall.R; 

public class OpponentService extends android.app.Service { 

    private boolean mRunning;//state 
    private static String service_tag = "MyService"; 
    private NotificationManager nm; 
    private static final int NOTIFICATION_ID_CONNECTED = 0; 

    private final int requestPeriod = 4000;//20seconds 
    final Handler handler = new Handler(); 
    private Timer timer = new Timer(); 
    private TimerTask invitesListenerServiceTask; 
    private InvitesManager incomingIvitesManager = new InvitesManager(); 

    public class LocalBinder extends Binder 
    { 
     public OpponentService getService() 
     { 
      return OpponentService.this; 
     } 
    } 

    private final IBinder mBinder = new LocalBinder(); 

    @Override 
    public IBinder onBind(final Intent intent) 
    { 
     Log.d(service_tag, "onBindService"); 
     return mBinder; 
    } 

    @Override 
    public boolean onUnbind(final Intent intent) 
    { 
     Log.d(service_tag, "onUnbindService"); 
     return super.onUnbind(intent); 
    } 

    @Override 
    public void onCreate() 
    { 
     mRunning = false; 
     super.onCreate(); 
     Log.d(service_tag, "onCreateService"); 
     nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
    } 

    @Override 
    public int onStartCommand(final Intent intent, final int flags, final int startId) 
    { 
     if (!mRunning) { 
      mRunning = true; 
     } 
     ii_listener_start(MPapi.getinstance().get_gameid(getApplicationContext())); 
     return START_STICKY; 
     //return START_NOT_STICKY; 
    } 

    @Override 
    public void onDestroy() 
    { 
     mRunning = false; 
     ii_listener_cancel(); 
     super.onDestroy(); 
     Log.d(service_tag, "onDestroyService"); 
    } 

    public void ii_listener_start(final int createdgame_id) { 
     invitesListenerServiceTask = new TimerTask() { 
      @Override 
      public void run() { 

       handler.post(new Runnable() { 
        public void run() { 
         incomingIvitesManager.get_invites_from_server(createdgame_id); 
         if (!incomingIvitesManager.RES_GETINVITES.equals("") && 
          !incomingIvitesManager.RES_GETINVITES.equals("invite")) { 
          ii_listener_cancel(); 
          restoreForeground(incomingIvitesManager.RES_GETINVITES); 
          //stopSelf();//stop service 
         } 
         else {} 
        } 
       }); 

      } 
     }; 

     timer.schedule(invitesListenerServiceTask, 0, requestPeriod);// execute in every 4s till success 
    } 

    public void ii_listener_cancel() { 
     //stopSelf();//stop service 
     if (invitesListenerServiceTask != null) 
      invitesListenerServiceTask.cancel(); 
    } 

    public void restoreForeground(String player2) { 
     final NotificationCompat.Builder notification = new NotificationCompat.Builder(OpponentService.this); 
     notification.setSmallIcon(R.drawable.chess_notification); 
     notification.setContentTitle(getString(R.string.app_name)); 
     notification.setContentText(getString(R.string.mp_opponent_ready, player2)); 
     notification.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, Single.class), 0)); 
     notification.setWhen(System.currentTimeMillis()); 
     notification.setOngoing(true); 
     notification.setAutoCancel(true); 
     notification.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 }); 
     nm.notify(NOTIFICATION_ID_CONNECTED, notification.getNotification()); 
    } 

} 

log:

08-17 01:49:44.662: E/AndroidRuntime(10372): FATAL EXCEPTION: main 

08-17 01:49:44.662: E/AndroidRuntime(10372): android.os.NetworkOnMainThreadException 

08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at java.net.InetAddress.getAllByName(InetAddress.java:214) 08-17 01:49:44.662: E/AndroidRuntime(10372):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.HttpWorker.getJSONFromUrl(HttpWorker.java:173) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.MP.InvitesManager.get_invites_from_server(InvitesManager.java:82) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at com.vasil.wall.chss.MP.OpponentService$1$1.run(OpponentService.java:97) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Handler.handleCallback(Handler.java:615) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Handler.dispatchMessage(Handler.java:92) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at android.os.Looper.loop(Looper.java:137) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at android.app.ActivityThread.main(ActivityThread.java:4867) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at java.lang.reflect.Method.invokeNative(Native Method) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at java.lang.reflect.Method.invoke(Method.java:511) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) 

08-17 01:49:44.662: E/AndroidRuntime(10372): at dalvik.system.NativeStart.main(Native Method) 

Antwort

1

Der Fehler ist genau so, wie die Ausnahme sagt, du bist Netzwerk Sachen auf dem Haupt (UI) Thread zu tun.

Um zu verstehen, warum Sie wissen müssen, dass new Handler() an den Thread bindet, auf dem es erstellt wird, der vermutlich der Hauptthread sein wird, da es während der Erstellung des Dienstes erstellt wird.

Dies bedeutet, dass die im Aufruf handler.post(..) ausgeführte Arbeit im Hauptthread ausgeführt wird, was die Ausnahme verursacht.

Um das Problem zu beheben, verwenden Sie entweder AsyncTask oder stellen Sie sicher, dass der Handler an einen anderen Looper gebunden ist, wenn er erstellt wird.

+0

Danke für die Antwort. ii_listener_start (MPapi.getinstance(). Get_gameid (getApplicationContext())); - Problem in dieser Zeile. Ich lege die Zeile in Thread http://StackOverflow.com/a/20644728 und AsyncTask - es wirft immer noch den Fehler. –

+1

@VitaliGrabovski Das Verschieben dieser Zeile wird das Problem nicht beheben, da '.get_invites_from_server (...)' immer noch mit dem Handler ausgeführt wird, der an den Hauptthread gebunden ist. Sie sollten auf Android-Nebenläufigkeit lesen, weil Sie verstehen müssen, was der Code tut, um dieses Problem zu lösen. – Kiskae

+0

Ich ersetzte Handler durch AsyncTask. Es funktioniert jetzt. –

Verwandte Themen