Service

● 有三个常用内置方法:onCreate()、onStartCommand()、onDestroy()
①onCreate():在服务第一次创建时调用
②onStartCommand(p1,p2,p3):在服务每次启动时调用,逻辑操作写在此方法中,p1是Intent对象,p2是整型标识符,p3是整型startId;当Android系统面临内存缺乏时可能会销毁一些Service,待内存充足再重新创建Service,Service被强制销毁并再次重建的行为依赖于onStartCommand()的返回值,常用的返回值有:
START_NOT_STICKY:当Service被杀掉后,不会重新创建该Service,直到接收到新的Intent对象。适用场景:在Service中定时从服务器中获取最新数据
START_STICKY:当Service被杀掉后,内存充足的情况下会重新创建该Service,但是不再保存Service被杀死前onStartCommand()传入的最后的Intent对象,这时系统会用一个null的Intent对象调用onStartCommand(),即onStartCommand()会执行但获取不到Intent里的信息。适用场景:Service可以在任何时刻运行或结束且不需要Intent信息,如媒体播放器
START_REDELIVER_INTENT:当Service被杀掉后,内存充足的情况下会重新创建该Service,但不同的是,系统会将Service被杀死前onStartCommand()传入的最后的Intent对象保留下来并传入onStartCommand(),这样就能读取到Intent信息,适用于下载文件;注意,在SDK2.0以前的版本中此方法被称为onStart(),不过它仍然有用
③onDestroy():在服务销毁时调用,回收资源的逻辑写在此方法中
● 每个服务都需要在AndroidManifest.xml中注册才能生效,这是四大组件的共同特点,AS会自动注册,例:

<application
...
>
...
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
</service>
</application>

enable和export属性在创建服务时会选择让用户勾选,enable表示是否启用这个服务,export表示是否允许除了当前程序之外的其他程序访问这个服务
● 启动和停止服务:
①启动和停止服务主要是借助Intent实现的,例:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);
这里的Intent的用法和"1.Intent的几种用法"中的几种用法都不同,但和第1个用法最像,我想这里应该是因为由于不是从一个页面跳转到另一个页面,所以p1就只写了一个this;
②startService§方法用于启动服务,p是Intent对象,与此对应的是stopService§方法,用于停止服务,这两个方法都是定义在Context类中的,所以在活动中可以直接调用(即不需要用其他类名或对象调用)
也可以让服务自己停止,用stopSelf()方法即可
③使用startService启动服务后,一定要使用stopService停止服务,不管是否使用bindService()
● 服务和进程间通信:即活动和服务进行绑定,使之关系更亲密
①需要用到的几个函数:
ServiceConnection类:里面有两个方法onServiceDisconnected§和onServiceConnected(p1,p2),onServiceDisconnected§在活动和服务绑定时调用,p是ComponentName对象,无返回值;onServiceConnected(p1,p2)在活动和服务解绑时调用,p1是ComponentName对象,p2是IBinder对象
bindService(p1,p2,p3):将活动和服务绑定,p1是Intent,这个Intent的创建方法是:Intent intent = new Intent(this,MyService.class);p2是ServiceConnect的实例;p3是一个标识位,传入BIND_AUTO_CREATE表示在活动和服务绑定后自动创建服务,这会使服务的onCreate()执行,而onStartCommand()不会执行
unBindService():活动和服务解绑;有bindService绑定到Service时,在某处就应当有unbindService()解绑,尽管Activity被finish时绑定会自动解除且Service会自动停止
onBind():当另一个组件想通过调用bindService()与服务绑定(例如执行RPC)时,系统将调用此方法,在此方法的实现中,必须通过返回IBinder提供一个接口,供客户端用来与服务进行通信,一定要实现此方法,但若并不希望允许绑定,应返回null
②服务和进程间通信的过程:
实现ServiceConnect,重写onServiceDisconnected()和onServiceConnected(),然后调用bindService(),之后当系统调用onServiceConnected()时,就算绑定成功,解绑时再调用unBindService()
这几个方法中会有IBinder和Binder接口和类,暂时不需了解它们的机制
例:
先自定义一个Service的子类MyService:

public class MyService extends Service {	

private DownloadBinder mBinder = new DownloadBinder();

//添加一个内部类,继承自Binder,Binder类暂时不需要深入了解
class DownloadBinder extends Binder{	
//省略的是这个类的功能方法的逻辑,如开始下载、查看进度等
......
}

@Override
//返回一个IBinder接口对象,暂时不需要深入了解IBinder接口,只需知道Binder是继承自IBinder接口的
public IBinder onBinder(Intent intent){
return mBinder;
}
}

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MyService.DownloadBinder downloadBinder;
//匿名方法实现ServiceConnect
private ServiceConnect connect = new Service(){
@Override
public void onServiceConnected(ComponentName name, IBinder service){		//ComponentName暂时不用深究,它代表组件名称
downloadBinder = (MyService.DownloadBinder)service;
downloadBinder.startDownload(); //调用DownloadBinder中的功能方法
}
@Override
public void onServiceDisconnected(ComponentName name){
}
};

@Override
protected void onCreate(......){
......
//按钮的绑定
}

@Override
public void onClick(View v){
switch(v.getId()){
...
case R.id.bind_service:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connect, BIND_AUTO_CREATE); //绑定服务
break;
case R.id.bind_service::
unBindService(connection);	//解绑服务
break;
default:
break;
}
}
}

点击按钮,就能实现服务与活动的绑定和解绑
● Service的生命周期:
①被启动的服务的生命周期:若一个Service被某个Activity调用Context.startService()启动,那么不管是否有Activity使用bindService()绑定或unbindService()解绑到该Service,该Service都在后台运行。若一个Service被startService()多次启动,那么onCreate()只会调用一次,而onStart()会调用多次(对应调用startService()的次数),且系统只会创建一个Service的一个实例(所以只需一次stopService()的调用),该Service直到被调用stopService()或自身的stopSelf()或系统资源不足被系统结束时这个Service才会停止
②被绑定的服务的生命周期:若一个服务被某个活动调用Context.bindService()绑定启动,不管调用bindService()几次,onCreate()都只会调用一次,onStart()不会被调用;当连接建立后,Service会一直运行,除非调用Context.unbindService()断开连接或之前调用bindService的Context不存在了(如Activity被finish时),系统将会自动停止Service,对应onDestroy()被调用
③被启动又被绑定的服务的生命周期:该Service会一直在后台运行,且不管如何调用,onCreate()始终只会调用一次,对应startService调用多少次,Service的onStart()就会调用多少次;调用unbindService()不会停止Service,必须调用stopService()或Service的stopSelf()
④当服务被停止时清除服务:当一个Service被终止时,onDestroy()被调用,在这里应做一些清除工作,如停止在Service中创建并运行的线程
● 需要注意的几点:
①同时使用startService()和bindService()时,Service的终止需要stopService()和unbindService()同时调用,不管startService()和bindService()的调用顺序,若先调用unbindService(),要再调用stopService()服务才会终止,若先调用stopService()服务也不会终止,要再调用unbindService()或之前调用bindService()的Context不存在了(如Activity被finish时)服务才会自动停止
②当手机屏幕在横竖之间旋转变化时,若Activity会自动旋转的话,旋转其实是Activity的重新创建,因此旋转之前使用bindService()建立的连接就会断开(Context不存在了),对应服务的生命周期与上述相同
③若只想提供绑定,则无需实现onStartCommand()方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值