简体   繁体   中英

Why it throws android.os.NetworkOnMainThreadException on service after activity destroyed?

I am using service to check the server state and notice user about it. It works fine until the app's activity destroyed. I keep the service even if activity destroyed but if fails each time. Any suggestions?

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)

The error is exactly as the exception says, you're doing network stuff on the main (UI) thread.

To understand why you need to know that new Handler() binds to the thread on which it is created, which will presumably be the main thread since it is created during construction of the service.

This means the work done in the handler.post(..) call will be executed on the main thread, causing the exception.

To fix the problem either use an AsyncTask or ensure the Handler is bound to a different Looper when it is created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM