[Android] Service服务详解以及如何使service服务不被杀死 (2)

要使用服务就必须在 manifest 文件声明要用的所有服务,只用在<application>标签内添加子标签<service>即可。

<manifest ...> ... <application ...> <service android:name=".ExampleService" android:enabled=["true" | "false"] android:exported=["true" | "false"] android:isolatedProcess=["true" | "false"] android:label="string resource" android:icon="drawable resource" android:permission="string" android:process="string" > ... </service> </application> </manifest>

下面对service标签属性做说明

android:name
你所编写的服务类的类名,可填写完整名称,包名+类名,如com.example.test.ServiceA,也可以忽略包名,用.开头,如.ServiceA,因为在manifest文件开头会定义包名,它会自己引用。

一旦你发布应用,你就不能改这个名字(除非设置android:exported="false"),另外name没有默认值,必须定义。

android:enabled
是否可以被系统实例化,默认为true

因为父标签<application>也有enable属性,所以必须两个都为默认值true的情况下服务才会被激活,否则不会激活。

android:exported
其他应用能否访问该服务,如果不能,则只有本应用或有相同用户ID的应用能访问。当然除了该属性也可以在下面permission中限制其他应用访问本服务。

这个默认值与服务是否包含意图过滤器intent filters有关。如果一个也没有则为false

android:isolatedProcess
设置true意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(binding and starting)。

android:label
可以显示给用户的服务名称。如果没设置,就用<application>的lable。不管怎样,这个值是所有服务的意图过滤器的默认lable。定义尽量用对字符串资源的引用。

android:icon
类似label,是图标,尽量用drawable资源的引用定义。

android:permission
是一个实体必须要运行或绑定一个服务的权限。如果没有权限,startService(),bindService()或stopService()方法将不执行,Intent也不会传递到服务。

如果属性未设置,会由<application>权限设置情况应用到服务。如果两者都未设置,服务就不受权限保护。

android:process
服务运行所在的进程名。通常为默认为应用程序所在的进程,与包名同名。<application>元素的属性process可以设置不同的进程名,当然组件也可设置自己的进程覆盖应用的设置。

如果名称设置为冒号:开头,一个对应用程序私有的新进程会在需要时和运行到这个进程时建立。如果名称为小写字母开头,服务会在一个相同名字的全局进程运行,如果有权限这样的话。这允许不同应用程序的组件可以分享一个进程,减少了资源的使用。

创建“启动的”服务

  启动的(started)服务由startService(Intent)方法启动,在服务中的onStartCommand()方法里获得Intent信息。关闭则由服务自己的方法stopSelf()或者由启动服务的地方调用stopService(Intent)方法来关闭。并不会因为启动服务的应用程序销毁而关闭。

  示例,一个应用需要保存数据到远程数据库,这时启动一个服务,通过创建启动的服务给服务传递数据,由服务执行保存行为,行为结束再自我销毁。因为服务跟启动它的应用在一个进程的主线程中,所以对于耗时的操作要起一个新的线程去做。

//activity中 Intent intent = new Intent(MainActivity.this, ServiceA.class); intent.putExtra("name", strName); startService(intent); //service中 @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub // 获取数据 String strName = intent.getStringExtra("name"); // ... 数据库操作 new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub 耗时的操作 } }).run(); return Service.START_STICKY; }

写服务有2种,继承service或者IntentService。后者是前者的子类。前者包含上面介绍的各种方法,用于普通的服务。后者可以自己开一个工作线程一个接一个处理多个请求。

继承IntentService

大多数服务不需要同时处理多个请求,继承IntentService是最好的选择

IntentService处理流程

创建默认的一个worker线程处理传递给onStartCommand()的所有intent,不占据应用的主线程

创建一个工作队列一次传递一个intent到你实现的onHandleIntent()方法,避免了多线程

在所以启动请求被处理后自动关闭服务,不需要调用stopSelf()

默认提供onBind()的实现,并返回null

默认提供onStartCommand()的实现,实现发送intent到工作队列再到你的onHandleIntent()方法实现。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysjwx.html