Service Automatic Called on Destroying Activity

后端 未结 4 928
天涯浪人
天涯浪人 2020-12-16 15:17

I am stuck with the problem of Activity + Service in that I have following number of Activities and Services.

Activities:

4条回答
  •  北海茫月
    2020-12-16 16:10

    You need to either run your service in the foreground so when the activity is destroyed so will the service or use a bound service and manage the binding with the activity lifecycle, so it is not continually restarted when the activity is destroyed.

    From this android docs tutorial Bound Services

    You need to do this for each service.

    public class CheckAutoSyncReceivingOrder extends Service {
        // Binder given to clients
        private final IBinder mBinder = new LocalBinder();
    
        public class LocalBinder extends Binder {
            CheckAutoSyncReceivingOrder getService() {
            return CheckAutoSyncReceivingOrder.this;
        }
    }
    
        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }   
    

    From your activity that creates and calls the service, that when it is destroyed you want your service destroyed.

    public class BindingActivity extends Activity {
        CheckAutoSyncReceivingOr mService;
        boolean mBound = false;
    
    
        @Override
        protected void onStart() {
            super.onStart();
            // Bind to CheckAutoSyncReceivingOr
            Intent intent = new Intent(this, CheckAutoSyncReceivingOr.class);
            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            // Unbind from the service
            if (mBound) {
                unbindService(mConnection);
                mBound = false;
            }
        }
    
        /** Defines callbacks for service binding, passed to bindService() */
        private ServiceConnection mConnection = new ServiceConnection() {
    
            @Override
            public void onServiceConnected(ComponentName className,
                IBinder service) {
                // We've bound to CheckAutoSyncReceivingOr, cast the IBinder and get CheckAutoSyncReceivingOr instance
                LocalBinder binder = (LocalBinder) service;
                mService = binder.getService();
                mBound = true;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName arg0) {
                mBound = false;
            }
        };
    }   
    

    And manage the service lifecycle. Restart the same service with your timer, do not create a new service.

    public class ExampleService extends Service {
        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
    
        @Override
        public void onCreate() {
            // The service is being created
        }
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // The service is starting, due to a call to startService()
            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() {
            // The service is no longer used and is being destroyed
        }
    }
    

    Note START_NOT_STICKY will only prevent the service from restarting if the device is low on memory.

    Be mindful that you where you are starting services, just start it once and allow the service to maintain it's own lifecycle until you destroy it with your activity.

    This is in reply to your original unedited question, when the app was mysteriously crashing:

    You need to destroy the dialog before the context window the dialog is attached to. That will cause a problem. So this is where program flow and the order of closing and cleaning up resources is important. They, frequently have to be destroyed in the reverse order they were created if they are dependent upon parent windows (which is often in the form of a particular activity).

    It's difficult to trace your code, so this is a generic answer.

    Make use of onPause and onDestroy in your activities.

    In all your activities, manage any resources you have created within that activity and with a null check, close them down. Like you have in your service class. If you want to override the parent onDestroy, place your custom code before super.onDestroy.

    protected void onDestroy() {
    
        if(timer != null)
            timer.cancel();
    
        Log.d(TAG, "Stopping Sending...");
    
        super.onDestroy();
    }
    

提交回复
热议问题