如何防止android应用中的service被系统回收

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止android应用中的service被系统回收相关的知识,希望对你有一定的参考价值。

永不被kill是不可能的,android系统应用都有可能会被kill,不要说用户应用了,只能说被kill以后还能重新启动。
Android中,当Service被kill后,如果重启需要使用BroadcastReceiver来实现,即广播接收者,例如利用BroadcastReceiver注册网络广播或者开关机广播,当接收到广播后直接启动service,这样就可以保证service被kill后,自动启动。
实现代码:
1.在配置文件AndroidManifest.xml中向系统注册BroadcastReceiver
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>

2.需要添加相应权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

3.在Receiver中就可以添加开机,或者网络状态改变后需要进行的操作
public class BootCompletedReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)



4.执行操作,Intent intent = new Intent(context,Service.class); context.startService(intent); 这样即可开机,或者网络状态改变后启动Service了。
参考技术A 在service中重写下面的方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动重写创建
@Override
public int onStartCommand(Intent intent, int flags, int startId)
// TODO Auto-generated method stub
Log.v("TrafficService","startCommand");

flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);


如何实现一个不会被杀死的进程
看Android的文档知道,当进程长期不活动,或系统需要资源时,会自动清理门户,杀死一些Service,和不可见的Activity等所在的进程。
但是如果某个进程不想被杀死(如数据缓存进程,或状态监控进程,或远程服务进程),应该怎么做,才能使进程不被杀死。
add android:persistent="true" into the <application> section in your AndroidManifest.xml
切记,这个不可滥用,系统中用这个的service,app一多,整个系统就完蛋了。
目前系统中有phone等非常有限的,必须一直活着的应用在试用。

如何防止Android应用中的Service被系统回收?
很多朋友都在问,如何防止Android应用中的Service被系统回收?下面简单解答一下。

对于Service被系统回收,一般做法是通过提高优先级可以解决,在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时实用于广播,推荐大家如果你的应用很重要,可以考虑通过系统常用intent action来触发。

Android防止Service被杀死

1. Service被杀死的两种场景

1.2 系统回收

在系统内存空间不足时可能会被系统杀死以回收内存,内存不足时Android会依据Service的优先级来清除Service

1.2 用户清除

用户可以在”最近打开”(多任务窗口、任务管理窗口)中清除最近打开的任务,当用户清除了Service所在的任务时,Service可能被杀死(不同ROM有不同表现,在小米、魅族等第三方产商定制ROM上一般会被立即杀死,在Android N上没有被立即杀死)。

2. 解决方案

对于第一种场景(系统回收),如果不用黑科技(双进程互开等),我们只能够尽量提高Service的优先级,一种比较好的方式是使用前台Service

对于第二种场景(用户手动清除),可以将启动Service的任务排除出系统的最近任务列表。

2.1 前台Service

前台Service是一种有前台界面(Notification)、优先级非常高的Service,只有在系统内存空间严重不足时,才会清除前台Service。

只需要在Service的onCreate() 或者 onStartCommand() 内调用startForeground,就能将Service转为前台Service。示例如下:


private Notification buildForegroundNotification() {
   Notification.Builder builder = new Notification.Builder(this);

   builder.setOngoing(true);

   builder.setContentTitle(getString(R.string.notification_title))
           .setContentText(getString(R.string.notification_content))
           .setSmallIcon(R.mipmap.ic_launcher)
           .setTicker(getString(R.string.notification_ticker));
   builder.setPriority(Notification.PRIORITY_MAX);
   return builder.build();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
   Log.e(TAG, "onStartCommand");

   WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
   mRootView = new FloatRootView(this);
   mRootView.attach(windowManager);
   mRootView.showBubble();
   startForeground(1, buildForegroundNotification());

   return START_STICKY;

}

2.2 移出最近任务

为了使Service不会被用户从”最近打开”中清除,我们可以将启动Service的任务从系统的最近应用列表中删除。做法是将任务ActivityexcludeFromRecents设为true,如下:


<activity android:name=".MainActivity"
         android:excludeFromRecents="true">
   <intent-filter>
       <action android:name="android.intent.action.MAIN"/>

       <category android:name="android.intent.category.LAUNCHER"/>
   </intent-filter>
</activity>

以上是关于如何防止android应用中的service被系统回收的主要内容,如果未能解决你的问题,请参考以下文章

Android防止Service被杀死

Android防止Service被杀死

如何防止android app被kill

Android中如何启用Service,如何停用Service

android如何检测哪些应用有service

如何让android的service一直在后台运行