Android Service详解

来源:互联网 发布:mac 电脑 foxmail设置 编辑:程序博客网 时间:2024/05/18 19:44

Android Service详解

1. 调用startService() 和 bindService()后,要销毁service必须**_同时调用_**stopService()和unbindService()方法才可以,因为:

  • 点击Stop Service按钮只会让Service停止;
  • 点击Unbind Service按钮只会让Service和Activity解除关联;

一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁;

2. Service和Thread的关系:没有半毛钱关系

  • Thread,用于开启一个子线程,在里面执行一些耗时操作就不会阻塞主线程的运行;
  • Service,最初的理解是用来处理一些“后台”任务的,就认为一些比较耗时的操作就可以放在这里
    (后台任务嘛),这就产生了混淆了;

其实Service也是运行在主线程中的。

3. 后台和和子线程的概念

Android 的后台指的是它的运行完全不依赖UI;通常Service中需要另外开启一个子线程来执行那些不需要UI的耗时操作的;

4. 为什么不在Activity中直接使用线程而采用Service?

关键在可控制性

  • Activity可以对Service进行很好的控制,所有的Activity都可以于Service进行关联,并且可以很
    好的操作Service中的方法,即使Activity被销毁了,只要重新创建就可以重新建立于Service的连接;
  • Activity对线程则是十分无奈的,当Activity被销毁之后,就没有其它方法再去获得之前创建的子线
    程的示例,而且一个Activity创建的子线程,另一个Activity是无法对其进行操作的。

5. RemoteService

虽然是单独开了一个进程(即和当前应用程序不再同一个进程中)且进行耗时操作也不会出现ANR(但只是不在界面上进行展示,即不会出现ANR弹出框)程序似乎不会继续向下运行。还有RemoteService是有弊端的,由于他和开启它的Activity不再同一个进程当中,就不能采用之前NormalService那样的方式进行bind操作了,这样会导致程序崩溃。

6. RemoteService供外部调用注意事项

在供给其它应用程序调用的时候,其在AndroidManifest.xml文件中定义时应设置属性:

android:exported=true

表示可以供外部访问;如果该RemoteService在声明的时候进行了权限保护,即使用了以下属性:

<permission    android:name="com.rainmonth.permission.AIDL_SERVICE"    android:protectionLevel="normal" />

那么调用该Service的外部应用使用该Service的时候必须先声明使用该Service自定义的权限,即:

<uses-permission android:name="com.rainmonth.permission.AIDL_SERVICE" />

否则提示not allowed to bind to service intent

注意:在其他应用调用该AIDL中定义的方法时,要保持包名及类名的一致;

7. Android 5.0以后的Service使用

Android 5.0以后要求声明使用Service的Intent必须是显式调用,如:

Intent intent = new Intent(context, XxxService.class);

而不能采用隐式调用,如:

Intent intent = new Intent("ActionString);

8. Android Studio中编写AIDL文件注意问题

编写完成后记得要先将项目***build***一下,否则在使用时会找不到AIDL中定义的方法;

9. IntentService的使用,

具体的逻辑处理主要发生在IntentService的回调方法onHandleIntent中,其实用可参见文章末尾的Demo,根据提供的示例可以发现IntentService应该是批量下载的绝佳实现方式了;

10. Service的开机启动

  1. AndroidManifest.xml文件中获取开机启动的权限;
  2. 定义一个BroadcastReceiver来监听boot_completed这个Action,如:

    <intent-filter>    <action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter>

    这样当手机启动后,就会出发该广播了;

  3. 在定义的BroadcastReceiver的onReceiver()方法中调用startService()方法即可;

11. Service在被杀死后重新启动

  1. 在Service的onDestroy()方法中进行重新启动该Service(简单的调用startService()
    方法)
    即可(前提是Service被杀死后会走onDestroy())这个生命周期函数;
  2. 在Service的onDestroy()方法中发送广播重新开启自己,然后自己接受这个广播;
  3. 开启两个服务A和B,A监听B的广播来启动B,B监听A的广播来启动A;
  4. 双进程守护,参考资料:
    • http://my.oschina.net/u/1777508/blog/345846;
    • http://blog.csdn.net/yyh352091626/article/details/50542554;

12. 降低服务因系统资源紧张而被杀死的方法:

  • 提高优先级(修改onStartCommand()方法的返回值);
  • 设置为前台Service(本质还是提高优先级);

Service Demo

0 0