美文网首页
如何像QQ一样进程不被系统杀死

如何像QQ一样进程不被系统杀死

作者: ZhouWG | 来源:发表于2018-04-18 14:17 被阅读0次

    如何像QQ一样进程不被系统杀死

    2018-01-29 香沙小熊 代码集中营

    点击上方“代码集中营”,选择“置顶公众号”

    优秀文章,第一时间送达!

    今天介绍一个android的Service,他是一个后台服务,专门用来处理常驻后台的工作组件。我们用的即时通讯,service来做常驻后台

    进程优先级

    进程的重要性优先级:

    1. 前台进程:Foreground process

    用户正在交互的Activity(onResume()

    当某个Service绑定正在交互的Activity

    被主动调用为前台的Service(startForeground())

    组件正在执行生命周期的回调((onCreate() /onStart()/onDestory())

    BroadcastReceiver 正在执行onReceive();

    2.可见进程:Visible process

    我们的Activity处在onPause() (没有进入onStop())

    绑定到前台Activity的Service

    3.服务进程:Service process

    简单的startservice()启动

    4.后台进程:Background process

    对用户没有直接影响的进程-----Activity处于onStop()的时候

    5.空进程    :Empty process

    不含有任何的活动的组件。(android设计的,为了第二次启动更快,采取了一个权衡)

    进程越往后越容易被系统杀死

    如何不被系统杀死

    我们要如何提升进程的优先级(尽量做到不轻易被系统杀死),提供以下七个方案

    1. 模仿QQ采取在锁屏的时候启动1个像素的Activity。

    背景:当手机锁屏的时候什么都干死了,为了省电。

    监听锁屏广播,锁了---启动这个1像素Activity。

    监听锁屏的,  开启---结束掉这个1像素Activity。

    要监听锁屏的广播---动态注册。

    关键代码:

    publicclassKeepLiveActivityManager{

    privatestaticKeepLiveActivityManager instance;

    privateContext context;

    privateWeakReference activityInstance;

    publicstaticKeepLiveActivityManagergetInstance(Context context){

    if(instance==null){

    instance =newKeepLiveActivityManager(context.getApplicationContext());

    }

    returninstance;

    }

    privateKeepLiveActivityManager(Context context){

    this.context = context;

    }

    publicvoidsetKeepLiveActivity(Activity activity){

    activityInstance =newWeakReference(activity);

    }

    publicvoidstartKeepLiveActivity(){

    Intent intent =newIntent(context, KeepLiveActivity.class);

    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    context.startActivity(intent);

    }

    publicvoidfinishKeepLiveActivity(){

    if(activityInstance!=null&&activityInstance.get()!=null){

    Activity activity = activityInstance.get();

    activity.finish();

    }    }

    }

    源码地址:https://github.com/kpioneer123/KeepLiveProcess

    2. 大型App运营商和手机厂商可能有合作关系---白名单

    3. 双进程守护

    一个进程被杀死,另外一个进程又被他启动,相互监听启动。

    A<---->B

    杀进程是一个一个杀的,本质是和杀进程时间赛跑。

    关键代码:

    publicclassLocalServiceextendsService{

    publicstaticfinalString ACTION_LOCAL_SERVICE ="com.haocai.app.keepliveprocess.LocalService";

    privatestaticfinalString TAG ="LocalService";

    privateMyServiceConnection conn;

    privateMyBinder binder;

    privateIntent testIntent;

    @Override

    publicvoidonCreate(){

    // TODO Auto-generated method stub

    super.onCreate();

    if(binder ==null){

    binder =newMyBinder();

    }

    conn =newMyServiceConnection();

    }

    @Nullable

    @Override

    publicIBinderonBind(Intent intent){

    returnbinder;

    }

    @Override

    publicvoidonDestroy(){

    super.onDestroy();

    if(testIntent!=null){

    stopService(testIntent);

    }

    //unbindService(conn);

    }

    //启动前台进程 增加重要性优先级

    @Override

    publicintonStartCommand(Intent intent,intflags,intstartId){

    LocalService.this.bindService(newIntent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

    PendingIntent contentIntent = PendingIntent.getService(this,0, intent,0);

    NotificationCompat.Builder builder =newNotificationCompat.Builder(this);

    builder.setTicker("360")

    .setContentIntent(contentIntent)

    .setContentTitle("我是360,我怕谁!")

    .setAutoCancel(true)

    .setContentText("hehehe")

    .setWhen( System.currentTimeMillis());

    //把service设置为前台运行,避免手机系统自动杀掉改服务。

    startForeground(startId, builder.build());

    returnSTART_STICKY;

    }

    classMyBinderextendsRemoteConnection.Stub{

    @Override

    publicStringgetProcessName()throwsRemoteException{

    // TODO Auto-generated method stub

    return"LocalService";

    }

    }

    classMyServiceConnectionimplementsServiceConnection{

    @Override

    publicvoidonServiceConnected(ComponentName name, IBinder service){

    Log.i(TAG,"建立连接成功!");

    }

    @Override

    publicvoidonServiceDisconnected(ComponentName name){

    Log.i(TAG,"本地服务被干掉了~~~~~断开连接!");

    Toast.makeText(LocalService.this,"断开连接", Toast.LENGTH_SHORT).show();

    //启动被干掉的

    testIntent =newIntent();

    //自定义的Service的action

    testIntent.setAction(RemoteService.ACTION_REMOTE_SERVICE);

    //自定义Service的包名

    testIntent.setPackage(getPackageName());

    Log.i("999", getPackageName() +"");

    startService(testIntent);

    LocalService.this.bindService(newIntent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

    }

    }

    }

    源码地址:https://github.com/kpioneer123/KeepLiveProcess2

    4. JobScheduler

    把任务加到系统调度队列中,当到达任务窗口期的时候就会执行,我们可以在这个任务里面启动我们的进程。这样可以做到将近杀不死的进程。

    @SuppressLint("NewApi")

    publicclassJobHandleServiceextendsJobService{

    publicstaticfinalString ACTION_JOB_HANDLE_SERVICE ="com.haocai.app.keepliveprocess.JobHandleService";

    privateintkJobId =0;

    @Override

    publicvoidonCreate(){

    super.onCreate();

    Log.i("INFO","jobService create");

    }

    @Override

    publicintonStartCommand(Intent intent,intflags,intstartId){

    Log.i("INFO","jobService start");

    scheduleJob(getJobInfo());

    returnSTART_NOT_STICKY;

    }

    @Override

    publicvoidonDestroy(){

    // TODO Auto-generated method stub

    super.onDestroy();

    }

    @Override

    publicbooleanonStartJob(JobParameters params){

    // TODO Auto-generated method stub

    Log.i("INFO","job start");

    //      scheduleJob(getJobInfo());

    booleanisLocalServiceWork = isServiceWork(this, LocalService.ACTION_LOCAL_SERVICE);

    booleanisRemoteServiceWork = isServiceWork(this, RemoteService.ACTION_REMOTE_SERVICE);

    //      Log.i("INFO", "localSericeWork:"+isLocalServiceWork);

    //      Log.i("INFO", "remoteSericeWork:"+isRemoteServiceWork);

    if(!isLocalServiceWork||

    !isRemoteServiceWork){

    //this.startService(new Intent(this,LocalService.class));

    startLocalService();

    startRemoteService();

    //this.startService(new Intent(this,RemoteService.class));

    Toast.makeText(this,"process start", Toast.LENGTH_SHORT).show();

    }

    returntrue;

    }

    privatevoidstartLocalService(){

    Intent  testIntent =newIntent();

    //自定义的Service的action

    testIntent.setAction(LocalService.ACTION_LOCAL_SERVICE);

    //自定义Service的包名

    testIntent.setPackage(getPackageName());

    Log.i("999",getPackageName()+"");

    startService(testIntent);

    }

    privatevoidstartRemoteService(){

    Intent testIntent =newIntent();

    //自定义的Service的action

    testIntent.setAction(RemoteService.ACTION_REMOTE_SERVICE);

    //自定义Service的包名

    testIntent.setPackage(getPackageName());

    Log.i("999", getPackageName() +"");

    startService(testIntent);

    }

    @Override

    publicbooleanonStopJob(JobParameters params){

    Log.i("INFO","job stop");

    //      Toast.makeText(this, "process stop", Toast.LENGTH_SHORT).show();

    scheduleJob(getJobInfo());

    returntrue;

    }

    /** Send job to the JobScheduler. */

    publicvoidscheduleJob(JobInfo t){

    Log.i("INFO","Scheduling job");

    JobScheduler tm =

    (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);

    tm.schedule(t);

    }

    publicJobInfogetJobInfo(){

    JobInfo.Builder builder =newJobInfo.Builder(kJobId++,newComponentName(this, JobHandleService.class));

    builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);

    builder.setPersisted(true);

    builder.setRequiresCharging(false);

    builder.setRequiresDeviceIdle(false);

    builder.setPeriodic(10);//间隔时间--周期

    returnbuilder.build();

    }

    /**

    * 判断某个服务是否正在运行的方法

    *

    *@parammContext

    *@paramserviceName

    *            是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)

    *@returntrue代表正在运行,false代表服务没有正在运行

    */

    publicbooleanisServiceWork(Context mContext, String serviceName){

    booleanisWork =false;

    ActivityManager myAM = (ActivityManager) mContext

    .getSystemService(Context.ACTIVITY_SERVICE);

    List myList = myAM.getRunningServices(100);

    if(myList.size() <=0) {

    returnfalse;

    }

    for(inti =0; i < myList.size(); i++) {

    String mName = myList.get(i).service.getClassName().toString();

    if(mName.equals(serviceName)) {

    isWork =true;

    break;

    }

    }

    returnisWork;

    }

    }

    5. 监听QQ,微信,系统应用,友盟,小米推送等等的广播,然后把自己启动了。

    6. 利用账号同步机制唤醒我们的进程AccountManager

    7. NDK来解决,Native进程来实现双进程守护。

    相关文章

      网友评论

          本文标题:如何像QQ一样进程不被系统杀死

          本文链接:https://www.haomeiwen.com/subject/yxjchftx.html