android.process.media crash后现象研究之二

做实验如下:


C:\>adb shell ps |grep android.process.media
app_14    817   197   107556 24456 ffffffff afd0c74c S android.process.media

F:\send_file>adb shell kill 817
F:\send_file>adb logcat


发现: 杀掉android.process.media后该进程并未被自动运行。根据前一文分析,如果进程中存在Service在运行或者有Provider等待运行则进程会被自动运行。按道理MediaScannerService应该存在,所以所在进程会被自动运行啊!!


仔细查看MediaScannserService.java代码如下,因此每条命令执行后均将执行stopSelf(),因此当crash进程被发现时,如果Scan已结束则media进程被重启。如果crash时scan尚未结束,则scheduleServiceRestartLocked被调用。

    private final class ServiceHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        { ...
            stopSelf(msg.arg1);
        }

 

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

而stopServiceToken当遇到请求stopService时,仅当startId为最后一次请求的id时才真正close Service。

ActivityManagerService.java

    public boolean stopServiceToken(ComponentName className, IBinder token,
            int startId) {
        synchronized(this) {
            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
                    + " " + token + " startId=" + startId);
            ServiceRecord r = findServiceLocked(className, token);
            if (r != null) {
                if (startId >= 0) {
                    // Asked to only stop if done with all work.  Note that
                    // to avoid leaks, we will take this as dropping all
                    // start items up to and including this one.
                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
                    if (si != null) {
                        while (r.deliveredStarts.size() > 0) {
                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
                            cur.removeUriPermissionsLocked();
                            if (cur == si) {
                                break;
                            }
                        }
                    }
                    
                    if (r.lastStartId != startId) { //只有当最后start的id才可触发关闭Service
                        return false;
                    }                    
                }
                
                synchronized (r.stats.getBatteryStats()) {
                    r.stats.stopRunningLocked();
                    r.startRequested = false;
                    r.callStart = false;
                }
                final long origId = Binder.clearCallingIdentity();
                bringDownServiceLocked(r, false);                //去掉Service记录
                Binder.restoreCallingIdentity(origId);
                return true;
            }
        }
        return false;
    }

故每次MediaScannerService中handlemessage处理完消息后会马上被关闭,因此media进程crash时,进程中并无Service注册与ActivityManagerService,因而进程未被自动运行。


如果在MediaScanner扫描媒体文件时android.process.media发生crash,则由于此时MediaScannerService正在运行,故ActivityManagerService将重启android.process.media进程并启动MediaScannerService。

至于进程中的Provider,即使有用户正在使用但Provider均已完成publish,则进程crash后ActivityManagerService并不会重启该进程。一旦进程被启动,其中的Provider将被自动运行。




你可能感兴趣的:(shell,service,kill,null,token,Crash)