美文网首页
从一个APP进程启动说起(下)

从一个APP进程启动说起(下)

作者: 我叫王菜鸟 | 来源:发表于2017-08-28 22:11 被阅读0次

    简介

    回顾我们上一次说的一个app进程的启动过程,比如现在是当我们点击桌面上应用的图标,就会通过AMS,也就是system_server进程去和zygoteinit所在进程也就是zygote进程通过socket方式将启动进程所需要的参数传递给zygote,zygote在一个循环中一直在监听,当监有数据到来时候将数据封装之后fork出来子进程,子进程创建完成之后做一些Android环境的初始化,最终通过抛出异常的方式将调用到ActivityThread.main方法中。

    我们今天的主题就接着上次说,开始我们可见的app之旅吧。

    简介

    回顾我们上一次说的一个app进程的启动过程,比如现在是当我们点击桌面上应用的图标,就会通过AMS,也就是system_server进程去和zygoteinit所在进程也就是zygote进程通过socket方式将启动进程所需要的参数传递给zygote,zygote在一个循环中一直在监听,当监有数据到来时候将数据封装之后fork出来子进程,子进程创建完成之后做一些Android环境的初始化,最终通过抛出异常的方式将调用到ActivityThread.main方法中。

    我们今天的主题就接着上次说,开始我们可见的app之旅吧。

    AT.main().png

    扫个盲

    //ZygoteInit.main()
    public static void main(String argv[]) {
        try {
            runSelectLoop(abiList);
            ....
        } catch (MethodAndArgsCaller caller) {
            caller.run(); 
        } catch (RuntimeException ex) {
            closeServerSocket();
            throw ex;
        }
    }
    

    我们昨天一开始就执行这段代码,这段代码最终又跑去子进程的这段代码中caller.run();所以故事发生在主线程

    1. ActivityThread.main()

    public static void main(String[] args) {
        //性能统计默认是关闭的
        SamplingProfilerIntegration.start();
        //将当前进程所在userId赋值给sCurrentUser
        Environment.initForCurrentUser();
    
        EventLogger.setReporter(new EventLoggingReporter());
        AndroidKeyStoreProvider.install();
    
        //确保可信任的CA证书存放在正确的位置
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
        Process.setArgV0("<pre-initialized>");
    
        //创建主线程的Looper对象, 该Looper是不运行退出
        Looper.prepareMainLooper();
    
        //创建ActivityThread对象
        ActivityThread thread = new ActivityThread();
    
        //建立Binder通道
        thread.attach(false);//[2]
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
    
        // 当设置为true时,可打开消息队列的debug log信息
        if (false) {
            Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop(); //消息循环运行
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    这里注意事项:

    ActivityThread还有一个地方可以创建就是在:

    SystemServer.run()
        createSystemContext()
            ActivityThread.systemMain()
                ActivityThread thread = new ActivityThread();
                thread.attach(true);//这里是true
    

    小节上面:

    • 创建主线程的Looper对象, 该Looper是不运行退出
    • 创建ActivityThread对象

    我们还要注意,在创建AT中发生了什么:

    • 创建了ResourcesManager对象
    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }
    
    • 成员变量中创建了ApplicationThread mAppThread = new ApplicationThread();
    • H mH = new H();给主线程发送消息的Handler对象

    2. ActivityThread.attach()

    ActivityThread.java

    //这里system=false
    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
             //开启虚拟机的jit即时编译功能
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
    
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //创建ActivityManagerProxy对象
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                //调用基于IActivityManager接口的Binder通道
                mgr.attachApplication(mAppThread);//[3]
            } catch (RemoteException ex) {
            }
    
            //观察是否快接近heap的上限
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        mSomeActivitiesChanged = false;
                        try {
                            //当已用内存超过最大内存的3/4,则请求释放内存空间
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                        }
                    }
                }
            });
        } else {
            ...
        }
        //添加dropbox日志到libcore
        DropBox.setReporter(new DropBoxReporter());
    
        //添加Config回调接口
        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                synchronized (mResourcesManager) {
                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                        if (mPendingConfiguration == null ||
                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                            mPendingConfiguration = newConfig;
                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
                        }
                    }
                }
            }
            @Override
            public void onLowMemory() {
            }
            @Override
            public void onTrimMemory(int level) {
            }
        });
    }
    

    这里做的事情:

    • ensureJitEnabled();具体是啥不知道
    • android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());设置进程名
    • 创建AMP
    • 给AMP绑定ApplicationThread对象
    • 看app进程内存情况,如果太大则释放内存
    • 给ViewRootImpl添加一个config的回调接口

    这里需要注意:
    final IActivityManager mgr = ActivityManagerNative.getDefault();

    static public IActivityManager getDefault() {
        return gDefault.get();
    }
    
    

    这里得到的Service是activity,activity是在SystemServer中通过AMS.setSystemProcess()中添加的服务,对应AMS

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    

    3. AMS.attachApplication()

    ActivityManagerService.java

    在这里我们把握一个核心,这里子进程已经通过Binder调用到了AMS所在进程,也就是system_server进程了

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {//此pid是调用者的pid
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord对象
            }
        } else {
            app = null;
        }
        if (app == null) {
            if (pid > 0 && pid != MY_PID) {
                //ProcessRecord为空,则杀掉该进程
                Process.killProcessQuiet(pid);
            } else {
                //退出新建进程的Looper
                thread.scheduleExit();
            }
            return false;
        }
    
        //还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }
    
        final String processName = app.processName;
        try {
            //绑定死亡通知,注意这里是ApplicationThread的代理对象要linkToDeath
            //也就是如果ApplicationThread(继承Binder)挂掉了在AppDeathRecipient中可以接收到信息
            AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName); //重新启动进程
            return false;
        }
    
        //重置进程信息
        app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息,这里超时是在AMS启动进程时候加上去的,所以这里一旦启动就要移除
    
        //系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    
        //app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
        //这里已经开始provider的操作了
        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
            msg.obj = app;
            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
        }
    
        try {
            ...
            //获取应用appInfo
            ApplicationInfo appInfo = app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info;
            ...
            // 绑定应用[4]
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            //更新进程LRU队列
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            //每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启
            startProcessLocked(app, "bind fail", processName);
            return false;
        }
    
        mPersistentStartingProcesses.remove(app);
        mProcessesOnHold.remove(app);
        boolean badApp = false;
        boolean didSomething = false;
    
        //Activity: 检查最顶层可见的Activity是否等待在该进程中运行
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                badApp = true;
            }
        }
    
        //Service: 寻找所有需要在该进程中运行的服务
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                badApp = true;
            }
        }
    
        //Broadcast: 检查是否在这个进程中有下一个广播接收者
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
            } catch (Exception e) {
                badApp = true;
            }
        }
        //检查是否在这个进程中有下一个backup代理
        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
            try {
                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                        mBackupTarget.backupMode);
            } catch (Exception e) {
                badApp = true;
            }
        }
        if (badApp) { //杀掉bad应用
            app.kill("error during init", true);
            handleAppDiedLocked(app, false, true);
            return false;
        }
        if (!didSomething) {
            updateOomAdjLocked(); //更新adj的值
        }
        return true;
    }
    

    我们这里必须小节一下:

    • 设置代表该应用进程的ProcessRecord对象的一些成员变量
    • 初步设置oo_adj的值,这个是进程优先级核心
    • 撤销PROC_START+TIMEOUT_MSG对应操作
    • 调用ApplicationThread的binderApplication
    • 通知应用进程启动Acivity,Service等组件其中用于启动activity的函数是realStartActivityLocked

    4. ApplicationThread.bindApplication()

    我们通过APP所在进程,然后通过binder跨到AMS,通过AMS做一些处理之后,然后又调用到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<String, IBinder> services, Bundle coreSettings) {
    
        if (services != null) {
            //保存AMS传递来系统service的信息
            ServiceManager.initServiceCache(services);
        }
    
        setCoreSettings(coreSettings);//给主线程发消息H.SET_CORE_SETTINGS保存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;
        sendMessage(H.BIND_APPLICATION, data);//[5]给主线程发送消息BIND_APPLICATION,将data传递过去
    }
    

    其中setCoreSettings(coreSettings);这一句也很重要

    private void handleSetCoreSettings(Bundle coreSettings) {
        synchronized (mResourcesManager) {
            mCoreSettings = coreSettings;
        }
        onCoreSettingsChange();
    }
    
    private void onCoreSettingsChange() {
        boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
        if (debugViewAttributes != View.mDebugViewAttributes) {
            View.mDebugViewAttributes = debugViewAttributes;
    
            // 由于发生改变, 请求所有的activities重启启动
            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);
            }
        }
    }
    

    5. ActivityThread.handleBindApplication(data);

    private void handleBindApplication(AppBindData data) {
    
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
        mCompatConfiguration = new Configuration(data.config);
        ...
    
        //设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名,前面那个名字不算
        Process.setArgV0(data.processName);
        android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
    
        if (data.persistent) {
            //低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量
            if (!ActivityManager.isHighEndGfx()) {
                HardwareRenderer.disable(false);
            }
        }
    
        //重置时区
        TimeZone.setDefault(null);
        Locale.setDefault(data.config.locale);
    
        //更新系统配置
        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
        mCurDefaultDisplayDpi = data.config.densityDpi;
        applyCompatConfiguration(mCurDefaultDisplayDpi);
    
        //获取LoadedApk对象[5.1]
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        ...
    
        // 创建ContextImpl上下文
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        if (!Process.isIsolated()) {
            final File cacheDir = appContext.getCacheDir();
            if (cacheDir != null) {
                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
            }
    
            //用于存储产生/编译的图形代码
            final File codeCacheDir = appContext.getCodeCacheDir();
            if (codeCacheDir != null) {
                setupGraphicsSupport(data.info, codeCacheDir);
            }
        }
        ...
    
        //当处于调试模式,则运行应用生成systrace信息
        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        Trace.setAppTracingAllowed(appTracingAllowed);
    
        //初始化 默认的http代理
        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
            Proxy.setHttpProxySystemProperty(proxyInfo);
        }
    
        if (data.instrumentationName != null) {
            ...
        } else {
            mInstrumentation = new Instrumentation();
        }
    
        //FLAG_LARGE_HEAP则清除内存增长上限
        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
        } else {
            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
        }
    
        try {
            // 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象[5.2]
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
    
            if (!data.restrictedBackupMode) {
                List<ProviderInfo> providers = data.providers;
                if (providers != null) {
                    installContentProviders(app, providers);
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }
    
            mInstrumentation.onCreate(data.instrumentationArgs);
            //调用Application.onCreate()回调方法.
            mInstrumentation.callApplicationOnCreate(app);
    
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
    }
    

    小节:

    • 创建一个Application对象,该对象是本进程中运行的第一个Application,是通过指LoadedApk
    • 如果该Application有ContentProvider则应该安装他们

    在这里就开始创建ContentProvider了,所以ContentProvider的创建比其他组件要早。

    5.1 ActivityThread.getPackageInfoNoCheck()

    public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }
    
    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }
    
            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
    
                if (mSystemThread && "android".equals(aInfo.packageName)) {
                    packageInfo.installSystemApplicationInfo(aInfo,
                            getSystemContext().mPackageInfo.getClassLoader());
                }
    
                if (differentUser) {
                    // Caching not supported across users
                } else if (includeCode) {
                    mPackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                } else {
                    mResourcePackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                }
            }
            return packageInfo;
        }
    }
    

    5.1做的事情主要就是创建了LoadedApk然后返回

    5.2 LoadedApk.makeApplication()

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        Application app = null;
    
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";//默认在这里
        }
    
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//创建ContextImpl对象
            //创建Application对象, 该对象名来自于mApplicationInfo.className.
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
    
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
            }
        }
    
        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
                .getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }
            //写R常量
            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }
        return app;
    }
    

    主要做了三件事

    • 创建ContextImpl对象
    • 创建Application对象, 该对象名来自于mApplicationInfo.className.
    • 重写了R常量

    扫个盲

    //ZygoteInit.main()
    public static void main(String argv[]) {
        try {
            runSelectLoop(abiList);
            ....
        } catch (MethodAndArgsCaller caller) {
            caller.run(); 
        } catch (RuntimeException ex) {
            closeServerSocket();
            throw ex;
        }
    }
    

    我们昨天一开始就执行这段代码,这段代码最终又跑去子进程的这段代码中caller.run();所以故事发生在主线程

    1. ActivityThread.main()

    public static void main(String[] args) {
        //性能统计默认是关闭的
        SamplingProfilerIntegration.start();
        //将当前进程所在userId赋值给sCurrentUser
        Environment.initForCurrentUser();
    
        EventLogger.setReporter(new EventLoggingReporter());
        AndroidKeyStoreProvider.install();
    
        //确保可信任的CA证书存放在正确的位置
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
        Process.setArgV0("<pre-initialized>");
    
        //创建主线程的Looper对象, 该Looper是不运行退出
        Looper.prepareMainLooper();
    
        //创建ActivityThread对象
        ActivityThread thread = new ActivityThread();
    
        //建立Binder通道
        thread.attach(false);//[2]
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
    
        // 当设置为true时,可打开消息队列的debug log信息
        if (false) {
            Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop(); //消息循环运行
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    这里注意事项:

    ActivityThread还有一个地方可以创建就是在:

    SystemServer.run()
        createSystemContext()
            ActivityThread.systemMain()
                ActivityThread thread = new ActivityThread();
                thread.attach(true);//这里是true
    

    小节上面:

    • 创建主线程的Looper对象, 该Looper是不运行退出
    • 创建ActivityThread对象

    我们还要注意,在创建AT中发生了什么:

    • 创建了ResourcesManager对象
    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }
    
    • 成员变量中创建了ApplicationThread mAppThread = new ApplicationThread();
    • H mH = new H();给主线程发送消息的Handler对象

    2. ActivityThread.attach()

    ActivityThread.java

    //这里system=false
    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
             //开启虚拟机的jit即时编译功能
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
    
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //创建ActivityManagerProxy对象
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                //调用基于IActivityManager接口的Binder通道
                mgr.attachApplication(mAppThread);//[3]
            } catch (RemoteException ex) {
            }
    
            //观察是否快接近heap的上限
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        mSomeActivitiesChanged = false;
                        try {
                            //当已用内存超过最大内存的3/4,则请求释放内存空间
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                        }
                    }
                }
            });
        } else {
            ...
        }
        //添加dropbox日志到libcore
        DropBox.setReporter(new DropBoxReporter());
    
        //添加Config回调接口
        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                synchronized (mResourcesManager) {
                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                        if (mPendingConfiguration == null ||
                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                            mPendingConfiguration = newConfig;
                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
                        }
                    }
                }
            }
            @Override
            public void onLowMemory() {
            }
            @Override
            public void onTrimMemory(int level) {
            }
        });
    }
    

    这里做的事情:

    • ensureJitEnabled();具体是啥不知道
    • android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());设置进程名
    • 创建AMP
    • 给AMP绑定ApplicationThread对象
    • 看app进程内存情况,如果太大则释放内存
    • 给ViewRootImpl添加一个config的回调接口

    这里需要注意:
    final IActivityManager mgr = ActivityManagerNative.getDefault();

    static public IActivityManager getDefault() {
        return gDefault.get();
    }
    
    

    这里得到的Service是activity,activity是在SystemServer中通过AMS.setSystemProcess()中添加的服务,对应AMS

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    

    3. AMS.attachApplication()

    ActivityManagerService.java

    在这里我们把握一个核心,这里子进程已经通过Binder调用到了AMS所在进程,也就是system_server进程了

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {//此pid是调用者的pid
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord对象
            }
        } else {
            app = null;
        }
        if (app == null) {
            if (pid > 0 && pid != MY_PID) {
                //ProcessRecord为空,则杀掉该进程
                Process.killProcessQuiet(pid);
            } else {
                //退出新建进程的Looper
                thread.scheduleExit();
            }
            return false;
        }
    
        //还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }
    
        final String processName = app.processName;
        try {
            //绑定死亡通知,注意这里是ApplicationThread的代理对象要linkToDeath
            //也就是如果ApplicationThread(继承Binder)挂掉了在AppDeathRecipient中可以接收到信息
            AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName); //重新启动进程
            return false;
        }
    
        //重置进程信息
        app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息,这里超时是在AMS启动进程时候加上去的,所以这里一旦启动就要移除
    
        //系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    
        //app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
        //这里已经开始provider的操作了
        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
            msg.obj = app;
            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
        }
    
        try {
            ...
            //获取应用appInfo
            ApplicationInfo appInfo = app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info;
            ...
            // 绑定应用[4]
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            //更新进程LRU队列
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            //每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启
            startProcessLocked(app, "bind fail", processName);
            return false;
        }
    
        mPersistentStartingProcesses.remove(app);
        mProcessesOnHold.remove(app);
        boolean badApp = false;
        boolean didSomething = false;
    
        //Activity: 检查最顶层可见的Activity是否等待在该进程中运行
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                badApp = true;
            }
        }
    
        //Service: 寻找所有需要在该进程中运行的服务
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                badApp = true;
            }
        }
    
        //Broadcast: 检查是否在这个进程中有下一个广播接收者
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
            } catch (Exception e) {
                badApp = true;
            }
        }
        //检查是否在这个进程中有下一个backup代理
        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
            try {
                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                        mBackupTarget.backupMode);
            } catch (Exception e) {
                badApp = true;
            }
        }
        if (badApp) { //杀掉bad应用
            app.kill("error during init", true);
            handleAppDiedLocked(app, false, true);
            return false;
        }
        if (!didSomething) {
            updateOomAdjLocked(); //更新adj的值
        }
        return true;
    }
    

    我们这里必须小节一下:

    • 设置代表该应用进程的ProcessRecord对象的一些成员变量
    • 初步设置oo_adj的值,这个是进程优先级核心
    • 撤销PROC_START+TIMEOUT_MSG对应操作
    • 调用ApplicationThread的binderApplication
    • 通知应用进程启动Acivity,Service等组件其中用于启动activity的函数是realStartActivityLocked

    4. ApplicationThread.bindApplication()

    我们通过APP所在进程,然后通过binder跨到AMS,通过AMS做一些处理之后,然后又调用到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<String, IBinder> services, Bundle coreSettings) {
    
        if (services != null) {
            //保存AMS传递来系统service的信息
            ServiceManager.initServiceCache(services);
        }
    
        setCoreSettings(coreSettings);//给主线程发消息H.SET_CORE_SETTINGS保存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;
        sendMessage(H.BIND_APPLICATION, data);//[5]给主线程发送消息BIND_APPLICATION,将data传递过去
    }
    

    其中setCoreSettings(coreSettings);这一句也很重要

    private void handleSetCoreSettings(Bundle coreSettings) {
        synchronized (mResourcesManager) {
            mCoreSettings = coreSettings;
        }
        onCoreSettingsChange();
    }
    
    private void onCoreSettingsChange() {
        boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
        if (debugViewAttributes != View.mDebugViewAttributes) {
            View.mDebugViewAttributes = debugViewAttributes;
    
            // 由于发生改变, 请求所有的activities重启启动
            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);
            }
        }
    }
    

    5. ActivityThread.handleBindApplication(data);

    private void handleBindApplication(AppBindData data) {
    
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
        mCompatConfiguration = new Configuration(data.config);
        ...
    
        //设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名,前面那个名字不算
        Process.setArgV0(data.processName);
        android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
    
        if (data.persistent) {
            //低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量
            if (!ActivityManager.isHighEndGfx()) {
                HardwareRenderer.disable(false);
            }
        }
    
        //重置时区
        TimeZone.setDefault(null);
        Locale.setDefault(data.config.locale);
    
        //更新系统配置
        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
        mCurDefaultDisplayDpi = data.config.densityDpi;
        applyCompatConfiguration(mCurDefaultDisplayDpi);
    
        //获取LoadedApk对象[5.1]
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        ...
    
        // 创建ContextImpl上下文
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        if (!Process.isIsolated()) {
            final File cacheDir = appContext.getCacheDir();
            if (cacheDir != null) {
                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
            }
    
            //用于存储产生/编译的图形代码
            final File codeCacheDir = appContext.getCodeCacheDir();
            if (codeCacheDir != null) {
                setupGraphicsSupport(data.info, codeCacheDir);
            }
        }
        ...
    
        //当处于调试模式,则运行应用生成systrace信息
        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        Trace.setAppTracingAllowed(appTracingAllowed);
    
        //初始化 默认的http代理
        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
            Proxy.setHttpProxySystemProperty(proxyInfo);
        }
    
        if (data.instrumentationName != null) {
            ...
        } else {
            mInstrumentation = new Instrumentation();
        }
    
        //FLAG_LARGE_HEAP则清除内存增长上限
        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
        } else {
            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
        }
    
        try {
            // 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象[5.2]
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
    
            if (!data.restrictedBackupMode) {
                List<ProviderInfo> providers = data.providers;
                if (providers != null) {
                    installContentProviders(app, providers);
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }
    
            mInstrumentation.onCreate(data.instrumentationArgs);
            //调用Application.onCreate()回调方法.
            mInstrumentation.callApplicationOnCreate(app);
    
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
    }
    

    小节:

    • 创建一个Application对象,该对象是本进程中运行的第一个Application,是通过指LoadedApk
    • 如果该Application有ContentProvider则应该安装他们

    在这里就开始创建ContentProvider了,所以ContentProvider的创建比其他组件要早。

    5.1 ActivityThread.getPackageInfoNoCheck()

    public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }
    
    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }
    
            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
    
                if (mSystemThread && "android".equals(aInfo.packageName)) {
                    packageInfo.installSystemApplicationInfo(aInfo,
                            getSystemContext().mPackageInfo.getClassLoader());
                }
    
                if (differentUser) {
                    // Caching not supported across users
                } else if (includeCode) {
                    mPackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                } else {
                    mResourcePackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                }
            }
            return packageInfo;
        }
    }
    

    5.1做的事情主要就是创建了LoadedApk然后返回

    5.2 LoadedApk.makeApplication()

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        Application app = null;
    
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";//默认在这里
        }
    
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//创建ContextImpl对象
            //创建Application对象, 该对象名来自于mApplicationInfo.className.
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
    
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
            }
        }
    
        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
                .getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }
            //写R常量
            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }
        return app;
    }
    

    主要做了三件事

    • 创建ContextImpl对象
    • 创建Application对象, 该对象名来自于mApplicationInfo.className.
    • 重写了R常量

    相关文章

      网友评论

          本文标题:从一个APP进程启动说起(下)

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