源码角度浅析App启动流程

     写这篇博客,其实我自己还有很多地方原理没有看懂(像Binder机制达到当前进程跟AMS进行通信),但并不是很影响看懂App启动主要做了一些什么事。

   看源码我是带着1个问题

    问题:Application具体在什么时候创建以及执行的onCreate

   众所周知App应用是从ActivityThread的main方法开始(以方便阅读我删掉了一些次要代码

   public static void main(String[] args) {
        //从这里我们可以知道 App以消息来驱动App的各种事件(Handler机制嘛,有机会我会写一遍关于Handler机制源码分析的博客)
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        //接下来,看看ActivityThread的attach的实现
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

 

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            // ...省略
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //这里拿到的IActivityManager,这里先打住忘下看。我搞清楚mgr它真正是什么,在哪里实例,搞清这个情况接下来看看ActivityManager的getService()
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //这里等一等,先搞清楚mgr
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    ....
            });
        } else {
           //...省略
        }
        // ...省略
    }
    /**
     * @hide
     */
    public static IActivityManager getService() {
        //赫赫...点击IActivityManagerSingleton就到了下面
        return IActivityManagerSingleton.get();
    }
    //这里... 
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
//这里先记住这个Context.ACTIVITY_SERVICE,
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
//看完这里,是不是有点什么感觉,这块Binder机制来实现获取到远程的一个代理类 am
//到此还是没搞懂这个am真正的实例在哪里,它的实现类是什么鬼
//要弄清这个问题,我要飙车了,直接去看一下ActivityManagerService的一个方法,请往下看
                }
            };
//这快的代码我是在ActivityManagerService拷贝过来的
public void setSystemProcess() {
        try {
            //这里,看Context.ACTIVITY_SERVICE 注册的AMS,看到这里我们应该知道上面的哪个am
            //真正实现就是ActivityManagerService
            //别问我怎么知道的,我也是看了《深入理解android内核设计》AMS专题才知道的,
            //要不然鬼知道AMS在这里注册的哈
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
           //...省略
        }
    }

OK,回到刚开始的ActivityThread的attach那里

final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }

到此已经知道了mgr他的真正实现是ActivityManagerService(我直接说AMS了),我们直接去去看看attachApplication(...)的实现(哦对了,先留意一下mAppThread它是当前进程跟远程AMS通信的接口)

下面是AMS相关实现

    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            //继续跟,往下看
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
            //...此处省略一堆代码
            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
            //这里AMS通过收集信息,然后通过进程通信把信息回传App进程。OK,下面我们再往会看看ActivityThread的一个内部类实现的IApplicationThread的bindApplication的方法
            if (app.instr != null) {
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {//这里会有惊喜,这次暂时不做分析这块流程
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        //...省略一路代码
        return true;
    }

回到ActivityThread的ApplicationThread(这里是App进程哦,不是AMS所在进程)

public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial) {

            if (services != null) {
                // Setup the service cache in the ServiceManager
                ServiceManager.initServiceCache(services);
            }

            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            //这里,sendMessage,然后跟进去其实就是ActivityThread一个内部Handler实例,继续
            sendMessage(H.BIND_APPLICATION, data);
        }

根据sendMessage的H.BIND_APPLICATION,我跟到了这里

public void handleMessage(Message msg) {
//...省略其它case
    case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
//...省略其它case
}

接下来看看handleBindApplication(data)实现

        Application app;
        try {
            //看到这里,Application在此处实例化(次于怎么创建的感兴趣的同学跟进去看看哈)
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }

            //...省略
            try {
                //这里跟进去就会发现 Application的onCreate再此处调用
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
            }
        } finally {
            
            if (data.appInfo.targetSdkVersion <= Build.VERSION_CODES.O
                    || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
                StrictMode.setThreadPolicy(savedPolicy);
            }
        }

到此Application的启动流程梦游了一遍,看源码需谨慎带着问题去源码里面走可以不容易迷失在源码里面

其实看看这些东西,有些问题可能会不言自明,比如App启动优化为什么在Application的onCreate进行优化...

最近一个多月公司大部分精力放在了小程序开发这块,时间充足,接下来要是有空我会写几遍关于App换皮肤,插件化的干货博客附带Demo

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值