启动startService()分析(2)

源码分析  2018年7月17日 pm8:09发布2个月前更新 91es.com站长
56 0 0

接上一篇《Android 6.0 启动startService()源码分析(1)》,依旧分析startService()启动过程。由于篇幅过长,分开记录,便于阅读。

10.4 ActivityManagerProxy.attachApplication

在上一篇中的代码中

 【获取的又是ActivityManagerProxy对象】
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread); 【 10.4 ActivityManagerProxy.attachApplication 】但最终还是跑到了ActivityManagerService中attachApplication中
            } catch (RemoteException ex) {
                // Ignore
            }

根据上一篇分析

ActivityManagerNative.getDefault()获取的就是ActivityManagerProxy对象(过程可以看上一篇中的分析,此处省略)

我们看ActivityManagerProxy.attachApplication()

    public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        【mRemote 就是Binder  此处发送ATTACH_APPLICATION_TRANSACTION出去,然后在ActivityManagerNative的onTransact】
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

经过mRemote.transac后,ATTACH_APPLICATION_TRANSACTION有传送到ActivityManagerNative的onTransact()中

ActivityManagerNative.onTransact()

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        ......
        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                【这里最终调用的是 10.5 ActivityManagerService.attachApplication() 】
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
        .....
}
10.5 ActivityManagerService.attachApplication()
    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            【10.6 ActivityManagerService.attachApplicationLocked】
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
10.6 ActivityManagerService.attachApplicationLocked
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

        if (app == null) {
            Slog.w(TAG, "No pending application record for pid " + pid
                    + " (IApplicationThread " + thread + "); dropping process");
            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
            if (pid > 0 && pid != MY_PID) {
                Process.killProcessQuiet(pid);
                //TODO: killProcessGroup(app.info.uid, pid);
            } else {
                try {
                    thread.scheduleExit();
                } catch (Exception e) {
                    // Ignore exceptions.
                }
            }
            return false;
        }

        // If this application record is still attached to a previous
        // process, clean it up now.
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }
        ......
        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                 【10.7 mServices.attachApplicationLocked 】
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

      ......

        return true;
    }
10.7 ActiveServices.attachApplicationLocked
    boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }

                    mPendingServices.remove(i);
                    i--;
                    【添加包名】
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                            mAm.mProcessStats);
		    【10.8 ActiveServices.realStartServiceLocked() 】
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception in new application when starting service "
                        + sr.shortName, e);
                throw e;
            }
        }
        // Also, if there are any services that are waiting to restart and
        // would run in this process, now is a good time to start them.  It would
        // be weird to bring up the process but arbitrarily not let the services
        // run at this point just because their restart time hasn't come up.
        if (mRestartingServices.size() > 0) {
            ServiceRecord sr = null;
            for (int i=0; i<mRestartingServices.size(); i++) {
                sr = mRestartingServices.get(i);
                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName))) {
                    continue;
                }
                mAm.mHandler.removeCallbacks(sr.restarter);
                mAm.mHandler.post(sr.restarter);
            }
        }
        return didSomething;
    }
10.8 ActiveServices.realStartServiceLocked()
    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        if (app.thread == null) {
            throw new RemoteException();
        }
        if (DEBUG_MU)
            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
                    + ", ProcessRecord.uid = " + app.uid);
        r.app = app;
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

        final boolean newService = app.services.add(r);
        【10.9 ActiveServices.bumpServiceExecutingLocked 发送SERVICE_TIMEOUT_MSG用来判断是否ANR】
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();

        【这是服务的首次启动流程,先执行scheduleCreateService,其实到了本地端就是实例化服务类,然后调用了其onCreate方法 】
        boolean created = false;
        try {
            if (LOG_SERVICE_START_STOP) {
                String nameTerm;
                int lastPeriod = r.shortName.lastIndexOf('.');
                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
                EventLogTags.writeAmCreateService(
                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
            }
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startLaunchedLocked();
            }
            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            【执行onCreate()方法 10.10 ActivityThread.scheduleCreateService】
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            Slog.w(TAG, "Application dead when creating service " + r);
            mAm.appDiedLocked(app);
            throw e;
        } finally {
            if (!created) {
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);

                // Cleanup.
                if (newService) {
                    app.services.remove(r);
                    r.app = null;
                }

                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }

        requestServiceBindingsLocked(r, execInFg);

        updateServiceClientActivitiesLocked(app, null, true);

        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }
        【11. 0 服务进入onStartCommand()】
        sendServiceArgsLocked(r, execInFg, true);

        if (r.delayed) {
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
            getServiceMap(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (r.delayedStop) {
            // Oh and hey we've already been asked to stop!
            r.delayedStop = false;
            if (r.startRequested) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
                        "Applying delayed stop (from start): " + r);
                stopServiceLocked(r);
            }
        }
    }
10.9 ActiveServices.bumpServiceExecutingLocked 发送SERVICE_TIMEOUT_MSG用来判断是否ANR

没写完,由于最近忙,没有大块时间,后续补上,不好意思

2018月6月11日写,先发出来。

 历史上的今天

  1. 2024: git log命令参数部分记录(0条评论)
  2. 2023: Android 中Bn和Bp介绍(0条评论)
  3. 2021: Dialog的简单使用(0条评论)
  4. 2021: 穆旦:冥想(0条评论)
  5. 2020: [摘]SeekBar的thumbOffset属性(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

Ubuntu16安装openjdk-7

Ubuntu16.04 安装openjdk-7-jdksudo apt-get install openjdk-7-jre 或者sudo apt-get install openjdk-7-jdkUbuntu16.04的安装源已经默认没有openjdk7了,所以要自己手动添加仓库,如下:...

startActivity之进程启动

前言今天简单的记录一下App进程的启动过程。继之前startActivity的分析(《startActivity源码分析1》和《startActivity源码分析2》)中的进程启动是一带而过的,聪明的你会发现,进程启动的大部分跟《Zygote的启动之二ZygoteInit》重合了。正文回到...

Launcher根据包名启动应用

前言很多项目中Launcher是有可能自定义的,毕竟Android原生的Launcher比较庞大,有时候需要的需求很简单,自己重新写Launcher也比较容易维护。为啥要根据包名启动,因为一个应用可能存在多个Activity,当按Home键退出后,再次从Launcher界面点击需要回到之前展示...

萧红:饿

“列巴圈”挂在过道别人的门上,过道好象还没有天明,可是电灯已经熄了。夜间遗留下来睡朦朦的气息充塞在过道,茶房气喘着,抹着地板。我不愿醒得太早,可是已经醒了,同时再不能睡去。厕所房的电灯仍开着,和夜间一般昏黄,好象黎明还没有到来,可是“列巴圈”已经挂上别人家的门了!有的牛奶瓶也规规矩矩地等在别的房间...

Git tag 简单使用

前言打标签像其他版本控制系统(VCS)一样,Git可以给仓库历史中的某一个提交打上标签,以示重要。比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)。在项目中,为了区分SOP的版本代码,常要求打标签。正文下面简单的介绍一下TAG的使用.列出标签git...

[摘]常见音视频格式

前言本文内容(音视频格式介绍)来源网络,这里我只是整合一下。好记性不如烂笔头正文常见的音频编码格式MP3全称是MPEG Audio Layer3。MP3是利用MPEG Audio Layer 3的技术,将音乐以1:10甚至1:12 的压缩率,压缩成容量较小的file。mp3能够在音质...