Android四大组件之Service

来源:互联网 发布:飞升化身诀数据 编辑:程序博客网 时间:2024/06/05 01:06

进程概述

  • foreground process-前台进程

正处于activity resume状态正处于bound服务交互的状态正处于服务在前台运行的状态(StartForeGround()被调用)Service生命周期正在被执行(onCreate(),onStart(),onDestroy())BroadcastReceiver正在执行onReceive()方法杀死foreground需要用户响应,因为这个安全优先级是最高的是用户操作所必须的,任一时间下,仅有少数进程会处于前台,仅当内存实在无法供给它们维持同时运行时才会被杀死。一般来说,在这种情况下,设备依然处于使用虚拟内存的状态,必须要杀死一些前台进程以用户界面保持响应。

  • visible process-可视进程

activity不在前端显示,但也没有完全隐藏,能够看得见,比如弹出一个对话框它包含了一个绑定至一个可视的activity的服务。可视进程依然被视为是很重要的,非到不杀死它们便无法维持前台进程运行时,才会被杀死。


  • Service process-服务进程

正在运行的service是由 startService() 方法启动的服务尽管服务进程不会直接为用户所见,但它们一般都在做着用户所关心的事情(比如在后台播放mp3)。所以系统会尽量维持它们的运行,除非系统内存不足以维持前台进程和可视进程的运行需要。

  • background process-后台进程

不可见状态的activity进程,onstop被调用包含目前不为用户所见的activity(Activity对象的 onStop() 方法已被调用)。这些进程与用户体验没有直接的联系,可以在任意时间被杀死以回收内存供前台进程、可视进程以及服务进程使用。

  • empty process-空进程

没有运行任何component的进程,保留这个进程主要是为了缓存的需要不包含任何活动应用程序组件。这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间。系统经常会杀死这种进程以保持进程缓存和系统内核缓存之间的平衡。


Service

Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念。

  • Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR
  • 不建议在service中做耗时的操作,否则会引起ANR异常
  • 如果想在服务中执行耗时的任务。有以下解决方案:
    • 在service中开启一个子线程
    • 可以使用IntentService异步管理服务

Service的创建

activity以及其它组件一样,你必须在你的应用的清单文件中注册service,并且这个类要继承Service.

    <manifest ... >        ...        <application ... >            <service android:name=".ExampleService" />            ...        </application>      </manifest>  

Service的生命周期

普通Service

绑定Service

被开启的service通过其他组件调用 startService()被创建。
  这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。
  当service被停止时,系统会销毁它。        被绑定的service是当其他组件(一个activity)调用bindService()来创建的。
  activity可以通过一个IBinder接口和service进行通信。
  activity可以通过 unbindService()方法来关闭这种连接。
  一个service可以同时和多个activity绑定,当多个activity都解除绑定之后,系统会销毁service。

从以上图示可以发现:service的生命周期可以分为三个状态:

  • 初始状态
    service在onCreate()中进行它的初始化工作
    比如,一个音乐播放service可以在onCreate()中创建播放音乐的线程
  • 活动状态
    从onStartCommand() 或onBind()被调用开始,它们各自处理由startService()或 bindService()方法传过来的Intent对象
  • 销毁状态
    在onDestroy()中释放残留的资源

Service中的onStartCommond四种返回值策略

  • START_STICKY

如果service进程被kill掉,保留service的状态为开始状态,但不保留传递的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

  • START_NOT_STICKY

“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

  • START_REDELIVER_INTENT

重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

  • START_STICKY_COMPATIBILITY

START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
强调一下系统默认的使用策略:public int onStartCommand(Intent intent, int flags, int startId) {onStart(intent, startId);return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;}可见,默认的策略是START_STICKY,支持服务意外终止重新创建的。

IntentService

  在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR,为了解决这样的问题,引入了IntentService.那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作.异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务。

IntentService特点:

  • 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
  •  创建了一个工作队列,来逐个发送intent给onHandleIntent()。
  • 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
  • 默认实现的onBind()返回null
  • 默认实现的onStartCommand()的目的是将intent插入到工作队列中


service保活技术,防止app进程被杀死

Android 进程拉活包括两个层面:

  •  提供进程优先级,降低进程被杀死的概率
  • 在进程被杀死后,进行拉活

然后从A、B两个方面详细介绍一下
service被手机自带清理工具清理后,重启service有以下几种方法:
1. 在service中重写onStartCommand方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动重写创建

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    return START_STICKY;}

2.再写另外一个apk,用一个广播来监听这个APK是否被关闭,如果是关闭了则重启这个APK
public class ProtectorHelperReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {                String pkg = "com.innofidei.myprotector";// 被kill的应用的包名                String action = pkg + ".action.START_SERVICE";// 重启service的acition                String str = intent.getData().toString().toLowerCase().replace("package:", "");                String data = intent.getAction();                  if (str != null && str.equals(pkg)) {                        if (data != null && data.equals("android.intent.action.PACKAGE_REMOVED")) {                                File file = new File("/sdcard/" + context.getPackageName() + "/ProtectorHelper.apk");                                file.delete();                                file.getParentFile().delete();                                Intent intent2 = new Intent(context, UninstallActivity.class);                                intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                context.startActivity(intent2);                        } else {                                context.sendBroadcast(new Intent(action));// 通知应用重启service                        }                }        }}

3.提高Android Service 优先级

Activity怎么和service绑定

1.Activity通过bindService(Intent service, ServiceConnection conn, int flags)跟Service进行绑定。



2.绑定成功以后,Service会将代理对象通过回调的形式传递给MyServiceConnection,这样我们就获取Service提供的代理对象



3.在Activity中可以通过startService和bindService方法启动Service。
注意: 如果想获取Service中提供的代理对象,那么必须通过bindService方法,进行绑定服务。
比如:音乐播放器,第三方支付等。
如果仅仅只是为了开启一个后台任务,那么可以使用startService方法。


目前就这么多了,之后如果想到了再添加到文章当中,很多地方都是借鉴的一些文章,仅仅是为了方便资料的查询.欢迎补充.final612liang@163.com



























0 0
原创粉丝点击