`
djun100
  • 浏览: 163741 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

如何让service被管理器杀死后自动重启

 
阅读更多
欢迎转载,转载请注明出自:www.androidkaifa.com 安卓开发网
笔者最近在一项目开发中遇到这样一个需求,要在自己应用中启动了一个service,这个service用来监听服务器发过来的推送信息并弹出一个对话框显示信息,所以需要保证这个service时时运行着,且不能被任务管理或是系统的设置等工具杀掉,如果services是被杀死,则需要自动重启这service,笔者在网上查询一下,找到一些类似的问题文章,现在把它在www.androidkaifa.com总结记录下来,以方便需要实现像我这样的要求的朋友有帮助,希望大家都能写永远不会被KILL掉的进程/服务,也就是不受系统垃圾回收机制(内存管理)影响。
网络对此问题的解决建议:
(1)
在service中重写onStartCommand方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动重写创建@Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; }
(2)
在Service的onDestroy()中重启Service.
public void onDestroy() {
Intent localIntent = new Intent();
localIntent.setClass(this, MyService.class);//销毁时重新启动Service
this.startService(localIntent);
}
对于(2)此解决方案,笔者自己写了一个代码测试了一下,1:如果是在系统的settings中的DOWNLOADED关闭整个应用(Force stop),则这个services类中的onDestory方法没有监听到(services类的onDestory方法的log没有打印日志),如果是在系统里的setting中的RUNNING杀掉项目services,则onDestory方法则会监听到(services类的onDestory方法的log有打印日志),所以对于此解决方案并不是一定适用,2:或是通过别的应用,直接kill掉我的应用时,也是不会调用services类的onDestory方法的,
(3)
再写另外一个apk,用一个广播来监听这个APK是否被关闭,如果是关闭了则重启这个APK,而这里我们为什么要用另外一个APK?因为被关闭的应用程序不能检测到自己被关闭的事件,只能接收到其他应用被关闭的广播。这个action的recever
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
}
}
}
}
(4)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.system">
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:allowClearUserData="false" android:process="system"
android:killAfterRestore="false"
>

这样应该可以了,我也是仿照那些不能被杀死的系统应用的AndroidManifest.xml写的,但是若要这样写,则需要源码环境编译能通过,eclipse是没有这权限编译的这项目的,
(5)
项目的功能配置文件AndroidManifest.xml 中添加:
android:persistent="true"//在<application>节点下面
(6)提高Android Service 优先级的方法:
我们先看一下系统一些的进程级别:
进入 $SDK/tools 运行命令:# adb shell dumpsys activity|grep oom_adj代码:Running Norm Proc #6: oom_adj=0ProcessRecord{43635cf012689:com.roiding.netraffic/10028} Running Norm Proc #5: oom_adj=7ProcessRecord{436feda012729:com.android.browser/10006} Running Norm Proc #4: oom_adj=8ProcessRecord{4367e83812761:android.process.acore/10016} Running Norm Proc #3: oom_adj=8ProcessRecord{43691cd812754:com.google.process.gapps/10000} Running PERS Proc #1: oom_adj=-12ProcessRecord{435067505941:com.android.phone/1001} Running PERS Proc #0: oom_adj=-100ProcessRecord{4348fde05908:system/1000}返 回的一大堆东西,观察 oom_adj 的值,如果是大于8一般就是属于 backgroud 随时可能被干掉,数值越小证明优先级
越高,被干掉的时间越晚。你看phone的程序是-12说明电话就是电话,其他什么都干了了,也的能接电话对吧。
另外还有一个-100的,更邪乎因为是 system 如果他也完蛋了,你得系统也就挂了,


Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。
当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者
服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。
但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。为什么是 foreground?默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,
也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。
当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。
(7)
请参看我的另一篇文章《怎样使一个Android应用不被系统或第三方应用杀死》,
(8)
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.v("TrafficService", "Bind");
state = BINLD;
//使用线程,该线程不会被销毁
return myBinder;
}


class TrafficBinder extends Binder {
public float his = history;
TrafficService getService(){
return TrafficService.this;
}
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
receiver = new NetReceiver();
IntentFilter nfilter=new IntentFilter();
nfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
this.registerReceiver(receiver, nfilter);
dealBuffer();
handler.post(createBrod);
Log.v("TrafficService", "Create "+history+" "+todayTraffic+" "+tempTraffic);
super.onCreate();

}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
state = UNBINLD;
Log.v("TrafficService", "Unbind");
return true;
}

@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
Log.v("TrafficService", "Rebind");
state = BINLD;;
super.onRebind(intent);

}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
handler.removeCallbacks(updateBrod);
momorybuffer();
nManger.cancel(R.layout.notifi);
unregisterReceiver(receiver);

Log.v("TrafficService", "destroy "+history+" "+todayTraffic+" "+tempTraffic);
super.onDestroy();
}

@Override
public boolean stopService(Intent name) {
// TODO Auto-generated method stub
momorybuffer();
nManger.cancel(R.layout.notifi);
Log.v("TrafficService",name.getAction());
Log.v("TrafficService", "stop "+history+" "+todayTraffic+" "+tempTraffic);
return super.stopService(name);
}



@Override
public intonStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v("TrafficService","startCommand");

flags =START_STICKY;
return super.onStartCommand(intent, flags, startId);
// returnSTART_REDELIVER_INTENT;
}
//在以上代码中的onstartCommand返回START_STICKY,同时在destory的最后重启了服务,这样就OK了,
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics