我写的service代码如下:
public class MyService extends Service{
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.e("TAG", "service onCreate");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e("TAG", "service onDestroy");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.e("TAG", "service onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
我之前重写了onStart方法但是eclipse提示我这个方法已经不建议使用了,已经开始使用onStartCommand,这是为什么呢?我百度了一下,下面这段话可能给出一些解释
stop service 有两种方法:
1.使用调用程序来停止一个service :即调用stopService();
2.使用service 本身来停止一个service:即调用stopSelf(int srvId);
我们来想象一个场景:
如果service被很多的程序并发调用的话,如果在某个程序里你调用了stopService();那么第二个程序来调用的时候service的服务已经关掉了,这样你又得去重新onCreate()下service,如果量大的话,开销将是很大的。那么怎么办呢?
推荐的方式就是第二种了。stopSelf(int srvId),参数是srv的id,该id在startCommand的时候创建,stopSelf(int srvId)执行的时候会发送id给startCommand(),匹配所关掉服务的id是否匹配,这样如果某个启动服务的程序结束之前另一个线程也调用了startCommand(),这样前面一个程序就无法使用stopSelf(int srvId)来关闭service了。因为id已经变更了。这样就可以节约开销。
我又在想为什么android要细化出oncreate和onstart这两种方法呢?一种不就都能实现了啊,下面能够给出一些解释
如果所有的初始化都在onCreate()中实现,会有什么问题?
首先,Activity的onCreate()被调用时,Activity还不可见,如果要做一些动画,既然视图还不存在,在onCreate中来启动动画,明显有问题;
其次,AActivity 切换到 BActivity,再切换到 AActivity(我们假定是AActivity的同一个实例),由于实例已经存在,所以onCreate不会再被调用,那AActivity从后台切换至前台时,有可能需要一些初始化,那就没法再被调用到了,也有问题;
如果所有的初始化都在onStart()中实现,会有什么问题?
首先,onCreate()注释中,是明确建议 setContentView()、findViewById() 要在 onCreate() 中被调用,但我实测了一下,在onStart()中调用 setContentView()、findViewById() 功能也是正常的;
其次,onStart() 被调用时,Activity可能是可见了,但还不是可交互的,onResume()的注释中都明确地说了这不是Activity对用户是可见的最好的指示器,onStart() 在这之前被调用,那有一些特殊的初始化相关的逻辑在这里被调用也会有问题。
那么这些方法在startService()的时候的调用顺序是什么样的,这里来做一下试验:
执行startService()方法
02-09 22:46:40.452: E/TAG(23332): service onCreate
02-09 22:46:40.452: E/TAG(23332): service onStartCommand
退出应用或者最小化在后台查看应用程序我们会看到一个后台服务在运行
当再次执行startService方法的时候
02-09 22:46:40.452: E/TAG(23332): service onCreate
02-09 22:46:40.452: E/TAG(23332): service onStartCommand
02-09 22:46:44.502: E/TAG(23332): service onStartCommand
02-09 22:46:47.142: E/TAG(23332): service onStartCommand
只执行了onStartCommand方法
执行stopService方法的时候
02-09 22:46:40.452: E/TAG(23332): service onCreate
02-09 22:46:40.452: E/TAG(23332): service onStartCommand
02-09 22:46:44.502: E/TAG(23332): service onStartCommand
02-09 22:46:47.142: E/TAG(23332): service onStartCommand
02-09 22:46:48.542: E/TAG(23332): service onDestroy
程序终止执行了onDestroy方法
接下来我们来看看startService和和bindService区别
首先修改代码如下在activity中添加如下代码
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
MyBinder binder = (MyBinder)service;
MyService bindService = binder.getService();
bindService.MyMethod();
}
};
在service中添加如下代码
public void MyMethod(){
Log.i("TAG", "BindService-->MyMethod()");
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.e("TAG", "service onBind");
return myBinder;
}
public class MyBinder extends Binder{
public MyService getService(){
return MyService.this;
}
}
private MyBinder myBinder = new MyBinder();
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.e("TAG", "service onUnbind");
return super.onUnbind(intent);
}
添加这两段代码的作用就是实现activity和service的绑定
当执行bindService(intent, conn, Context.BIND_AUTO_CREATE);时打印的log日志如下:
02-10 17:26:21.337: E/TAG(15498): service onCreate
02-10 17:26:21.337: E/TAG(15498): service onBind
02-10 17:26:21.347: I/TAG(15498): BindService-->MyMethod()
可以看到并没有执行onStartCommand()方法而是执行了onBinda方法恰恰是这个方法反回了绑定的对象然后activity执行了ServiceConnection 中的onServiceConnected方法打印了第三行语句
当执行unbindService(conn);时打印的日志如下:
02-10 17:26:49.687: E/TAG(15498): service onUnbind
02-10 17:26:49.687: E/TAG(15498): service onDestroy
bindservice和startservice会不会同时出现呢,反正我是没有遇到过,在这就简单的说一下
start-bind-unbind-stop如下:
02-10 17:38:48.767: E/TAG(15498): service onCreate
02-10 17:38:48.767: E/TAG(15498): service onStartCommand
02-10 17:38:51.797: E/TAG(15498): service onBind
02-10 17:38:51.807: I/TAG(15498): BindService-->MyMethod()
02-10 17:38:55.187: E/TAG(15498): service onUnbind
02-10 17:38:57.417: E/TAG(15498): service onDestroy
start-bind-stop-unbind如下:
02-10 17:44:39.647: E/TAG(19316): service onStartCommand
02-10 17:44:40.517: E/TAG(19316): service onBind
02-10 17:44:40.527: I/TAG(19316): BindService-->MyMethod()
02-10 17:44:41.537: E/TAG(19316): service onUnbind
02-10 17:44:41.537: E/TAG(19316): service onDestroy
bind-start-unbind-stop如下:
02-10 17:45:20.497: E/TAG(19316): service onCreate
02-10 17:45:20.507: E/TAG(19316): service onBind
02-10 17:45:20.507: I/TAG(19316): BindService-->MyMethod()
02-10 17:45:21.647: E/TAG(19316): service onStartCommand
02-10 17:45:22.897: E/TAG(19316): service onUnbind
02-10 17:45:23.967: E/TAG(19316): service onDestroy
这说明当执行bindService之后必须要执行unbindService才能stop,即便先执行了stopService也不能destroy掉servvice,oncreate只能执行一次
其实没有必要太过纠结这两种情况同时出现的时候,这种情况我还没有遇到过。