Android_Service(基础篇)
Android中的四大组件之一:Service,Service是默默运行在后台的。它和其他组件一样,也是需要在AndroidManifest.xml文件中注册的。
下面我们来看一下一个普通的Service是如何创建的,Service是一个抽象类,这就说明我们继承Service这个抽象类。
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Service的主要作用就是在后台默默运行,那么它主要执行的逻辑代码,应该写在哪里呢?我想你肯定不会像到onBind()方法吧,因为,从字面的意思就可以看出来它是绑定的意思了。其实主要的逻辑代码写在onStartCommand()方法中。
1、onCreate():服务创建的时候调用。
2、onstartCommand():服务启动的时候调用。
3、onDestroy():服务销毁的时候调用。
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService","onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("MyService","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("MyService","onDestory()");
super.onDestroy();
}
最后在AndroidManifest.xml文件中注册该Service;
<service android:name=".MyService"/>
启动和停止服务
代码很简单就不多解释了。服务让自己停止的方法:stopSelf()
public class MainActivity extends Activity implements View.OnClickListener {
private Button startServiceBtn, stopServiceBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
startServiceBtn = (Button) findViewById(R.id.main_startService);
stopServiceBtn = (Button) findViewById(R.id.main_stopService);
startServiceBtn.setOnClickListener(this);
stopServiceBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_startService:
//启动服务
Intent intentStartService = new Intent(MainActivity.this, MyService.class);
startService(intentStartService);
break;
case R.id.main_stopService:
//停止服务
Intent intentStopService = new Intent(MainActivity.this, MyService.class);
stopService(intentStopService);
break;
}
}
}
当我们点击startService按钮的时候,我们可以看见log日志:
06-06 18:58:32.274 2014-2014/com.example.servicetest I/MyService: onCreate()
06-06 18:58:32.274 2014-2014/com.example.servicetest I/MyService: onStartCommand
当我么点击stopService按钮的时候,我们可以看见log日志:
06-06 18:59:39.344 2014-2014/com.example.servicetest I/MyService: onDestory()
活动和服务进行通信
一个活动可以调用startService或者stopService来启动或者停止服务,但是当服务执行完任务以后想要更新一下UI,那么该怎么办呢?这就需要活动和服务进行通信:通信的方法有两种:一个是运用onBind()方法,另一个就是运用BroadcastReceiver。今天只是讲解一下比较简单的onBind()方法,以后再去讲解另一种方法。
我们通过MyService中的onBind()方法可以看出该方法返回一个IBind,那我们就来定义一个类,来实现这个返回值。
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("MyService", "onBind()");
return mBinder;
}
private DownLoadBinder mBinder = new DownLoadBinder();
/**
* Binder类实现了IBinder接口
*/
class DownLoadBinder extends Binder {
public void startDownload() {
Log.i("MyService", "startDownload()");
}
public int getProgress() {
Log.i("MyService", "getProgress()");
return 0;
}
}
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService", "onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("MyService", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("MyService", "onDestory()");
super.onDestroy();
}
}
MainActivity中的代码如下:
public class MainActivity extends Activity implements View.OnClickListener {
private Button startServiceBtn, stopServiceBtn, bindService, unbindService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
startServiceBtn = (Button) findViewById(R.id.main_startService);
stopServiceBtn = (Button) findViewById(R.id.main_stopService);
bindService = (Button) findViewById(R.id.main_bindService);
unbindService = (Button) findViewById(R.id.main_unbindService);
startServiceBtn.setOnClickListener(this);
stopServiceBtn.setOnClickListener(this);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_startService:
//启动服务
Intent intentStartService = new Intent(MainActivity.this, MyService.class);
startService(intentStartService);
break;
case R.id.main_stopService:
//停止服务
Intent intentStopService = new Intent(MainActivity.this, MyService.class);
stopService(intentStopService);
break;
case R.id.main_bindService:
//绑定服务
Intent intentBindService = new Intent(MainActivity.this, MyService.class);
bindService(intentBindService,connection,BIND_AUTO_CREATE);
break;
case R.id.main_unbindService:
//解绑服务
unbindService(connection);
break;
}
}
private MyService.DownLoadBinder downLoadBinder=null;
private ServiceConnection connection =new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
downLoadBinder=(MyService.DownLoadBinder)service;
downLoadBinder.startDownload();
downLoadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
1、当我们点击BindService按钮的时候,我们可以看一下Log日志:
06-06 19:22:03.264 2975-2975/com.example.servicetest I/MyService: onCreate()
06-06 19:22:03.264 2975-2975/com.example.servicetest I/MyService: onBind()
06-06 19:22:03.274 2975-2975/com.example.servicetest I/MyService: startDownload()
06-06 19:22:03.274 2975-2975/com.example.servicetest I/MyService: getProgress()
由日志,我们可以清楚的看见Service中的DownLoadBinder类中的方法被调用了。所以说,我们可以在Activity中控制Service中的方法,让Service中的方法什么时候执行都可以。
2、当我们点击UnBindService按钮的时候,我们来看一下Log日志:
06-06 19:30:53.634 2975-2975/com.example.servicetest I/MyService: onDestory()
在此我想对bindService()这个方法进行一下说明,该方法接受三个参数,第一个参数就是构建出来的Intent对象,第二个参数就是创建出的ServiceConnection的实例,第三个参数则是一个标志位,这里传入BIND_AUTO_CREATE表示在活动和服务进行绑定后自动创建服务。这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
onServiceDisconnected()
在ServiceConnection中的onServiceDisconnected()将在绑定意外断开时被回调,正常断开绑定并不会回调该方法
onRebind()
在Service中的onRebind()方法表示“当重新绑定”时会回调的方法,该方法通常不会被回调,因为只有“绑定 -> 断开 -> 绑定”才是重新绑定,但是“断开”时Service将被销毁,导致第2次“绑定”到新的对象,则不会是“重新绑定”
如果要实现“重新绑定”,则应该先通过startService()激活Service组件,然后通过bindService()绑定相同的Service组件,当再次断开时,由于没有调用stopService(),则该Service不会被销毁,下次再次绑定时即为“重新绑定”
服务的生命周期
1、使用startService(Intent service)可以激活Service组件,在通过该方法激活的Service中,会经历的生命周期:
1) onCreate()
2) onStartCommand()
3) onDestory()
可以反复的调用startService()激活同一个Service组件,但是,该Service组件只会创建1次,
后续的反复激活只会重新经历onStartCommand()
通过stopService(Intent intent)可以停止Service,在Service内部,也可以通过stopSelf()方法停止当前Service
2、绑定Service是通过bindService()方法激活Service组件的方式
通过绑定Service,可以实现其它组件(例如Activity)可以直接调用Service组件中的方法
绑定模式的Service的生命周期:
onCreate() -> onBind() -> onDestory()
在Service中的onBind()方法的返回值不可以为null,否则绑定将不成功,
在Activity端的ServiceConnection中的方法不会被回调,在Activity端也不可能得到有效的IBinder对象
Service的粘性
使用startService(Intent service)激活的Service组件默认是粘性的,
表现为:被意外终止后,会自动的重启(onCreate() -> onStartCommand())
在Service中,onStartCommand()方法的返回值决定了它的粘性:
Service.START_NOT_STICKY:非粘性的
Service.START_STICKY:粘性的
Service.START_STICKY_COMPATIBILITY:兼容的粘性的【默认】
Service.START_REDELIVER_INTENT:粘性的,并且重启Service时会重新传递Intent