Android Service生命周期

是这样在的,我在app运行的时候开启服务,然后退出app并在后台清除该app时,在Service的OnDestroy方法中打log发现并没有走该方法,并且在判断服务的方法中发现该服务仍旧存活。所以这种现象是正常现象吗,原因是什么,我怎样才能在清理后台的时候把这个app的service也关闭?

还有一件事就是,我在Service里面开了一个线程,线程在后台清理后被关闭了,可是线程的标志位改变是在OnDestroy方法中被执行的,难道线程是被系统强制关闭的?

猜测跟service的onstartcommand方法的返回值有关,当返回值为某些值时,在service被非正常杀死时,service有机会自动复活

onDestroy()是在当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等,这是服务接收的最后一个调用。
所以如果使用startService()或者stopSelf()方法请求停止服务,系统会就会尽快销毁这个服务。
如果使用bindService绑定的服务,需要使用unbindService方法来进行解绑销毁。

这个应该是不正常的那么把代码发来看一下吧

这个应该是不正常的那么把代码发来看一下吧

我就是写一个很简单的服务DEMO
public class TestService extends Service{

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    Log.d("TestService", "onCreate");
    super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("TestService", "onStartCommand");
    //startThread();
    testService();
    return super.onStartCommand(intent, flags, startId);
}
public void testService()
{
    Log.d("TestService", "testService");
}

private void startThread() {
    new Thread(new Runnable() {

        @Override
        public void run() {
            while(true)
            {
                Log.d("test", "testtttt");
            }
        }
    }).start();
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    Log.d("TestService", "onDestroy");
    super.onDestroy();
}

}
MainActivity:
public class MainActivity extends Activity implements OnClickListener {
private Button isService;
private Button stopService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    isService = (Button) findViewById(R.id.isService);
    stopService = (Button) findViewById(R.id.stopService);

    isService.setOnClickListener(this);
    stopService.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.isService:

        Intent intent = new Intent(this, TestService.class);
        if (CommonUtil.isServiceRunning(getApplicationContext(), TestService.class)) {
            Toast.makeText(getApplicationContext(), "1111", 0).show();
        } else {
            startService(intent);

        }
        break;

    case R.id.stopService:
        Intent intent2 = new Intent(this, TestService.class);
        stopService(intent2);
        break;
    default:
        break;
    }
}

}

CommonUtil.isServiceRunning方法实现:
public static boolean isServiceRunning(Context context,
Class<? extends Service> clazz) {
ActivityManager manager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);

    List<RunningServiceInfo> services = manager.getRunningServices(100);
    for (int i = 0; i < services.size(); i++) {
        String className = services.get(i).service.getClassName();
        if (className.equals(clazz.getName())) {
            return true;
        }
    }
    return false;
}

就是长按Android 小圆点跳出程序列表的时候把它划掉。可以看到DDMS里面的程序被关闭了,但是一会儿又被开启了,这时候对服务判断发现仍旧存活,说明从列表中划去的操作并没有完全关闭服务。
图片说明

被强制关闭就不会走onDestroy方法了

如果想在界面退出时同时销毁后台服务 需要通过 绑定服务 的方式 即: 界面打开时 开启服务 , 界面退出时 停止服务;

下面是我下的案列 你参考下:

Activity中的代码:

private ServiceConnection serviceConnection;
private Context context;
private Intent service;

     @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_bind_service_layout);
    context = this;
    //开启服务
    service = new Intent(context, MyService.class);
    startService(service);
    //创建绑定服务的连接桥
    serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

                        /**
                            *IBinder iBinder 如果服务里 onBind()返回了 该对象 那么这里可以间接地使用服务中的方法
                            */

            ToastUtils.showToast(context, "serviceConnection 服务已绑定");
            LogUtils.showLog("bindService", "serviceConnection 服务已绑定");
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            ToastUtils.showToast(context, "serviceConnection 服务已解绑");
            LogUtils.showLog("bindService", "serviceConnection 服务已解绑");
        }
    };
    //开始绑定服务
    bindService(service, serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
    /**
     * 界面退出时解除绑定  绑定服务 必须 先解绑 ,再销毁
     */
    if (serviceConnection != null) {
        //解除绑定
        unbindService(serviceConnection);
        //销毁服务
        stopService(service);
        LogUtils.showLog("bindService", "Activity 中的服务已解绑 ");
    }
    super.onDestroy();
}



Service 中的代码:

  public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {

    return null;//这里可以自定义IBinder类 activity就可以使用service中的方法了
}

@Override
public void onCreate() {
    super.onCreate();

    ToastUtils.showToast(this, "Service 服务开启");
    LogUtils.showLog("bindService", "Service 服务已开启");
}

@Override
public void onDestroy() {

    ToastUtils.showToast(this, "服务销毁");
    LogUtils.showLog("bindService", "Service 服务已销毁");

    super.onDestroy();
}

}

你确定线程被关闭了??线程除非自己结束,否则是不归Service管的。如果能这么关掉,就没有内存泄漏的说法了。而且根据你那个任务管理器是不会关闭Service,取决不同的手机,一般手机在分页键里面不会关闭服务,需要去点击应用的强制停止才能

stone_you 这个朋友说的对,

sercice启动分为 startService和 bindService ,这2个service的启动方式,startSerice 是相当于注册service,除非调用stopSelf结束service才走destroy,与App是否退出无关。
bindService是绑定service,App退出时 会 onUnbind --onDestroy 来解除service

http://www.cnblogs.com/mengdd/archive/2013/03/24/2979944.html