1.Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的操作。
2.Android中进程的种类
Foreground process 前台进程
Visible process 可视进程, 可以看见, 但不可以交互.
Service process 服务进程
Background process 后台进程
Empty process 空进程(当程序退出时, 进程没有被销毁,而是变成了空进程)
3.当回收服务,系统非必要情况下不会轻易回收, 如果需要回收掉这三种进程,那么在系统内存够用时,
会再给重新启动进程;但是服务进程如果用户手动的关闭服务,这时服务不会再重启了。
4.为什么用服务而不是线程
Android应用程序刚启动都会开启一个进程给这个程序来使用。 Android一个应
用程序把所有的界面关闭时, 进程这时还没有被销毁,处于空进程状态,Thread运行在空进程中,很容易的被销毁了。
服务不容易被销毁, 如果非法状态下被销毁了, 系统会在内存够用时,重新启动。
5.如何使用Service
创建Service,定义类继承Service, AndroidManifest.xml中定义<service>
开启Service,在其他组件中调用startService方法
startService(intent);(在activity中可以直接调用),会执行onstartCommand(生命周期方法),如果发现service还没有,就会先创建执行oncreate。
onCreate只会执行一次,服务一旦被创建出来,就不会再执行onCreate方法,以后再去开启服务只会执行onStartCommand。
停止Service,调用stopService方法,会执行onDestory()(生命周期方法)
服务也是运行在主线程中,耗时操作需要放到子线程中,不然会出现anr
setForegound(true)(直接在service里调用),为了避免服务被杀死,我们可以指定这个服务为前台进程。
服务在执行生命周期方法时,也是一个前台进程。广播接收者也一样,在执行生命周期方法onReceive时,也是一个前台进程。
6.
/**
* 绑定服务时调用
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(new MyPhoneListener(),PhoneStateListener.LISTEN_CALL_STATE);
状态: TelephoneManager.CAll_state_idle:电话处于空闲状态, call_state_ringing,电话处于铃响状态。call_state_offbook:解除锁定,电话处于接听状态。
在MainActivity类中启动Service:
Intent service = new Intent();
service.setClass(this, MyService.class);
startService(service);
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
7.Service的生命周期
可以有两条不同的路径。服务有两种开启方式,一个是直接onstart,另一个是绑定服务。
started service(标准开启模式)
其他组件调用startService()被创建。这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它
bound service(绑定模式)
其他组件(一个客户)调用bindService()来创建的,客户可以通过一个IBinder接口和service进行通信。客户可以通过
unbindService()方法来关闭这种连接。一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service
绑定服务方法: bindService(intent,serviceConnection,intflag);在其他组件中调用此方法,调用后服务内部的生命周期方法onBind方法执行,一旦绑定成功, onBind只执行一次,再次绑定, onBind不会执行。
第二个参数: serviceConnection:连接对象,连接上服务之后可以调用服务的方法传入一个自定义的ServiceConnection用来接收Ibinder。实例化ServiceConnection对象,重写内部方法: onServiceConnected(ComponentName name,Ibinderbinder):绑定成功获取连接时,执行的方法。
参数: IBinder对象:接收服务内部onBind方法,返回的对象(通过这个对象可以间接的访问到服务内部的方法)
第三个参数: Bind_auto_create,如果绑定的这个服务没有创建,那么自动创建这个服务,调用生命周期方法onCreate()方法。
unBindService()解除绑定服务,内部调用服务的生命周期方法onUnbind(),然后调用onDestory()销毁服务。服务只能被解除绑定一次,如果unBindService方法被调用多次,就会出错
8.启动与绑定的区别
通过start()直接启动服务:服务一旦开启,就与调用者没有任何关系,调用者的activity即使退出,也不会影响后台服务的运行。
通过bindService()绑定服务:通过绑定方式开启的服务,服务跟调用者不求同生但求同死。注意:如果一个程序的activity绑定了服务,那么这个activity退出时,会报异常,说是服务没有被释放。那么我们可以重写activity的onDestory方法,方法内调用unbindService(),去显示的解除与服务的绑定。
第二个不同点:
Start直接启动服务的方法,调用者不能调用服务内部的方法。绑定服务启动服务的方法,调用者可以调用服务内部的方法利用serviceConnection接口获取服务onbind返回的ibinder对象,这个对象同时实现了自定义的接口,这个接口内定义了服务中的方法。
时间: 2024-11-02 08:53:09