进程管理--之三

2.4 进程垃圾回收

2.4.1 进程回收

MyActivityManagerService的runProcessGC主要逻辑如下,

1,调用ActivityManager的getRunningAppProcesses方法获取当前宿主框架的运行进程,

ActivityManager am = (ActivityManager) mHostContext.getSystemService(Context.ACTIVITY_SERVICE);
if (am == null) {
    return;
}

List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();
List<RunningAppProcessInfo> myInfos = new ArrayList<RunningAppProcessInfo>();

当然, IactivityManagerHookHandle的内部类getRunningAppProcesses的afterInvoke方法在此就不论述了。

2, 如果是插件进程(非宿主进程), 按进程优先级排序,调用doGc方法杀掉优先级较低的进程。

Collections.sort(myInfos, sProcessComparator);
   for (RunningAppProcessInfo myInfo : myInfos) {
        if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_GONE) {
           doGc(myInfo);
        } else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_EMPTY) {
           doGc(myInfo);
        } else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
           doGc(myInfo);
        } else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_SERVICE) {
           doGc(myInfo);
        } /*else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE) {
           //杀死进程,不能保存状态。但是关我什么事?
      }*/ else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE) {
            //杀死进程
      } else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
            //看得见
     } else if (myInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            //前台进程。
     }
}

doGc方法的逻辑如下,

1, 首先kill没有任何activity、service、provider的空进程

int activityCount = mRunningProcessList.getActivityCountByPid(myInfo.pid);
    int serviceCount = mRunningProcessList.getServiceCountByPid(myInfo.pid);
    int providerCount = mRunningProcessList.getProviderCountByPid(myInfo.pid);
       if (activityCount <= 0 && serviceCount <= 0 && providerCount <= 0) {
           //杀死空进程。
         Log.i(TAG, "doGc kill process(pid=%s,uid=%s processName=%s)", myInfo.pid, myInfo.uid, myInfo.processName);
         try {
              android.os.Process.killProcess(myInfo.pid);
         } catch (Throwable e) {
             Log.e(TAG, "error on killProcess", e);
         }

直接调用Process的killProcess方法kill进程。

2, 对于没有activity,只有service的进程,获取该进程的所有服务,调用stopSelf()停掉服务

else if (activityCount <= 0 && serviceCount > 0 /*&& !mRunningProcessList.isPersistentApplication(myInfo.pid)*/) {
   List<String> names = mRunningProcessList.getStubServiceByPid(myInfo.pid);
  if (names != null && names.size() > 0) {
       for (String name : names) {
            Intent service = new Intent();
            service.setClassName(mHostContext.getPackageName(), name);
            AbstractServiceStub.startKillService(mHostContext, service);
            Log.i(TAG, "doGc kill process(pid=%s,uid=%s processName=%s) service=%s", myInfo.pid, myInfo.uid, myInfo.processName, service);
       }
  }
}

调用AbstractServiceStub 的startKillService 方法Kill进程的service。

2.4.2 service回收

AbstractServiceStub的startKillService方法如下,

public static void startKillService(Context context, Intent service) {
    service.putExtra("ActionKillSelf", true);
    context.startService(service);
}

也是启动该服务,只是多了一个string信息。

AbstractServiceStub的onStart方法对该信息处理如下,

if (intent.getBooleanExtra("ActionKillSelf", false)) {
     startKillSelf();
     if (!ServcesManager.getDefault().hasServiceRunning()) {
          stopSelf(startId);
          boolean stopService = getApplication().stopService(intent);
     •••

首先看startKillSelf,该方法如下,

private void startKillSelf() {
        if (isRunning) {
            try {
                new Thread() {
                    @Override
                    public void run() {
                        synchronized (sLock) {
                            try {
                                sLock.wait();
                            } catch (Exception e) {
                            }
                        }
                        Log.i(TAG, "doGc Kill Process(pid=%s,uid=%s has exit) for %s 2", android.os.Process.myPid(), android.os.Process.myUid(), getClass().getSimpleName());
                        android.os.Process.killProcess(android.os.Process.myPid());
                    }
                }.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

开启了一个子线程,并且加锁等待,如果持有线程锁,就会调用Process的killProcess方法杀死进程。

那什么时候持有锁的地方会释放锁呢?在onDestroy方法当中,

public void onDestroy() {
        try {
            mCreator.onDestroy();
        } catch (Exception e) {
            handleException(e);
        }
        super.onDestroy();
        isRunning = false;
        try {
            synchronized (sLock) {
                sLock.notifyAll();
            }
        } catch (Exception e) {
        }
    }

当服务被回收时,就会kill服务所在的进程。

Service的stopSelf方法如下,

public final void stopSelf(int startId) {
        if (mActivityManager == null) {
            return;
        }
        try {
            mActivityManager.stopServiceToken(
                    new ComponentName(this, mClassName), mToken, startId);
        } catch (RemoteException ex) {
        }
    }

调用AMS的stopServiceToken 方法停止服务。当然会调用IactivityManagerHookHandle的内部类stopServiceToken的beforeInvoke方法,

前面已论述过程,在此就不论述了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值