1 public class startService1 extends Service { 2 static final String TAG="startService1 :"; 3 public startService1() { 4 super(); 5 } 6 7 @Override 8 public void onCreate() { 9 L.e(TAG,"onCreate");10 super.onCreate();11 }12 13 @Override14 public void onStart(Intent intent, int startId) {15 L.e(TAG,"onStart");16 super.onStart(intent, startId);17 }18 19 @Override20 public int onStartCommand(Intent intent, int flags, int startId) {21 L.e(TAG,"onStartCommand");22 return super.onStartCommand(intent, flags, startId);23 }24 25 @Override26 public void onDestroy() {27 L.e(TAG, "onDestroy");28 super.onDestroy();29 }30 31 @Override32 public void onConfigurationChanged(Configuration newConfig) {33 L.e(TAG, "onConfigurationChanged");34 super.onConfigurationChanged(newConfig);35 }36 37 @Override38 public void onLowMemory() {39 L.e(TAG, "onLowMemory");40 super.onLowMemory();41 }42 43 @Override44 public void onTrimMemory(int level) {45 L.e(TAG, "onTrimMemory");46 super.onTrimMemory(level);47 }48 49 @Override50 public IBinder onBind(Intent intent) {51 L.e(TAG, "onBind");52 return null;53 }54 55 @Override56 public boolean onUnbind(Intent intent) {57 L.e(TAG,"onUnbind");58 return super.onUnbind(intent);59 }60 61 @Override62 public void onRebind(Intent intent) {63 L.e(TAG, "onRebind");64 super.onRebind(intent);65 }66 67 @Override68 public void onTaskRemoved(Intent rootIntent) {69 L.e(TAG, "onTaskRemoved");70 super.onTaskRemoved(rootIntent);71 }72 73 @Override74 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {75 L.e(TAG, "dump");76 super.dump(fd, writer, args);77 }78 }
1.Activity.startService方式启动 service启动顺序如下:
06-04 11:16:00.147 17810-17810/com.alipay E/startService1 :﹕ --> onCreate
06-04 11:16:00.147 17810-17810/com.alipay E/startService1 :﹕ --> onStartCommand
06-04 11:16:00.147 17810-17810/com.alipay E/startService1 :﹕ --> onStart
如果连续startService(intent);startService(intent); 可见service只会create一次,start不限
06-04 11:49:27.877 19224-19224/com.alipay E/startService1 :﹕ --> onCreate
06-04 11:49:27.877 19224-19224/com.alipay E/startService1 :﹕ --> onStartCommand
06-04 11:49:27.887 19224-19224/com.alipay E/startService1 :﹕ --> onStart
06-04 11:49:27.887 19224-19224/com.alipay E/startService1 :﹕ --> onStartCommand
06-04 11:49:27.887 19224-19224/com.alipay E/startService1 :﹕ --> onStart
如果stopService(intent);可见service在onDestroy结束生命周期
06-04 11:53:06.027 19677-19677/com.alipay E/startService1 :﹕ --> onDestroy
可见本地Service控制方式很单一,并没有activity的保存唤醒功能。
如果finish开始service的activity,service并没有被销毁,可见startService方式启动service,只能调用stopservice来stop,跟所启动的activity的生命周期无关。
也就是说,一旦startService,这个Service就与此activity基本无关了。所以非常适合做常驻后台操作(非常耗时操作还是要启用新的线程,经测试service耗时也会导致ANR,很容易理解因为四大基本组件公用UI线程的MessageQueue嘛)
这里注意onXXXX操作并不都是立即执行,需要考虑到延时。
service->ContextWrapper->context,Activity->ContextThemeWrapper->ContextWrapper->context。而ContextThmeWrapper也就增加了一个initializeTheme方法,可见activity可以看做是有theme有view的service;
06-04 12:12:20.767 20538-20538/com.alipay E/AM_MEMORYIPROCESS﹕ --> onDestroy
2.Activity.bindService方式启动
我们先看一下bindService的参数,多了一个ServiceConnection.必须ServiceConnection非空,否则会抛出异常 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.alipay/com.alipay.startActivity}: java.lang.IllegalArgumentException: connection is null .ServiceConnection包括连接和断开连接的回调函数,如下.
public boolean bindService(Intent service, ServiceConnection conn,
int flags)
ServiceConnection serviceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
我们再来看看conn的flag.定义值之外不能成功bind.
public static final int BIND_AUTO_CREATE = 0x0001;
public static final int BIND_DEBUG_UNBIND = 0x0002;
public static final int BIND_NOT_FOREGROUND = 0x0004;
public static final int BIND_ABOVE_CLIENT = 0x0008;
public static final int BIND_ALLOW_OOM_MANAGEMENT = 0x0010;
public static final int BIND_WAIVE_PRIORITY = 0x0020;
public static final int BIND_IMPORTANT = 0x0040;
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
再来看看service的onbind方法。如果没有返回binder,onBind时serviceConnection的onServiceConnected方法并没有回调。
@Override
public IBinder onBind(Intent intent) {
L.e(TAG, "onBind");
return null;
}
06-04 15:26:42.803 23684-23684/com.alipay E/Service2﹕ --> onCreate
06-04 15:26:42.803 23684-23684/com.alipay E/Service2﹕ --> onBind
如果onBind返回binder,onServiceConnected回调成功。此处我理解是activity和service ipc的一种方式,serviceConnection此处定义在activity内,onbind定义在service内,
当activity bindservice时,回调onServiceConnected,完成彼此的通信。binder的proxy模式此处不详细讨论了。
@Override
public IBinder onBind(Intent intent) {
L.e(TAG, "onBind");
return binder;
}
06-04 15:31:15.633 23813-23813/com.alipay E/Service2﹕ --> onCreate
06-04 15:31:15.643 23813-23813/com.alipay E/Service2﹕ --> onBind
06-04 15:31:15.713 23813-23813/com.alipay E/AM_MEMORYIPROCESS﹕ --> onServiceConnected
我们再来看看unbind时候的生命周期,先unbind,再调用onDestroy结束service.我们可知,不管什么方式启动service,service只能create一次(注意service没有onstop onResume onPause等操作)
还要注意一点 onbind方式启动service,根本不会启动onstart.
再次验证 onbind时候执行超时操作一样会ANR,得出结论执行异步超时操作一定要新建线程,下一节讲怎么新建线程。
06-04 15:37:52.683 24057-24057/com.alipay E/Service2﹕ --> onCreate
06-04 15:37:52.683 24057-24057/com.alipay E/Service2﹕ --> onBind
06-04 15:37:52.683 24057-24057/com.alipay E/Service2﹕ --> onUnbind
06-04 15:37:52.683 24057-24057/com.alipay E/Service2﹕ --> onDestroy
3.同时启动onstart onBind Service,必须同时解绑才能销毁service.
bindService(intent, serviceConnection,BIND_AUTO_CREATE);
startService(intent);
stopService(intent);
unbindService(serviceConnection);
06-04 15:56:54.663 25250-25250/com.alipay E/Service2﹕ --> onCreate
06-04 15:56:54.663 25250-25250/com.alipay E/Service2﹕ --> onBind
06-04 15:56:54.673 25250-25250/com.alipay E/Service2﹕ --> onStartCommand
06-04 15:56:54.673 25250-25250/com.alipay E/Service2﹕ --> onStart
06-04 15:56:54.673 25250-25250/com.alipay E/Service2﹕ --> onUnbind
06-04 15:56:54.673 25250-25250/com.alipay E/Service2﹕ --> onDestroy
其实很容易理解,onstart启动本地service,onbind启动远程代理类service,必须将这两个service的资源都释放掉才能销毁service。
我们可以得出结论,onCreate和onDestroy是对应的,在service生命周期只会出现一次,分别在生命的开始和结束。onbind和onUnbind的是对应的。