安卓Android 启动相关知识点

Android App启动(下文)

2021-12-02  本文已影响0人  圣明

ps:Android 27
本文从ActivityThread#main开始,一只到Application创建结束

首先是发生在ActivityThread内的

我们先来看下入口main函数

ActivityThread.main

public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        ...
        Looper.loop();
    }

ActivityThread 重要成员

# 负责进程间通信的IApplicationThread.stub对象
final ApplicationThread mAppThread = new ApplicationThread();
private class ApplicationThread extends IApplicationThread.Stub {
 ...
}

# 负责主线程消息分发的消息Handler
final H mH = new H();
private class H extends Handler {
 ...
}

IApplicationThread.java

ActivityThread. attach

// 不是系统进程,所以system是false
private void attach(boolean system) {
        ...
        if (!system) {
           ...
            // 获取系统 AMS
            final IActivityManager mgr = ActivityManager.getService();
            try {
                // attach mAppThread ( IApplicationThread.stub) to ams
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
           ...
        } 
        ...
    }

现在我们转到AMS

Ams也是一个Stub类,实现了IActivityManager.stub 接口,为了跨进程通信,我们来看看AmsattachApplication方法做了哪些

ActivityManagerService.attachApplication

public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

ActivityManagerService.attachApplicationLocked

两件事:

private final boolean attachApplicationLocked(IApplicationThread thread,int pid){
        // 找到已经创建的Application record
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }
        ...
       // 调回 ActivityThread
      if (app.instr != null) {
           thread.bindApplication(...)
      }
      ...
      if (normalMode) {
            try {
                // 尝试启动第一个Activity
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
      }
}

然后再转到ActivityThread内查看ApplicationThread

ActivityThread.ApplicationThread#bindApplication

public final void bindApplication(xxxx) {
      ...
      // 往主线程发送一个BIND_APPLICATION的消息
      sendMessage(H.BIND_APPLICATION, data);
}

ActivityThread.H#handleMessage(Message msg)

public void handleMessage(Message msg) {
       switch (msg.what) {
           case BIND_APPLICATION:
               AppBindData data = (AppBindData)msg.obj;
               handleBindApplication(data);
               break;
      }
}

ActivityThread#handleBindApplication

private void handleBindApplication(AppBindData data){
        Application app;
        try {
            ....
            // 创建Application对象
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            ...
            try {
                // 执行application的onCreate()
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ..
            }
        } 
}

LoadedApk#makeApplication

public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
        ...
        Application app = null;
        // 获取Application的全路径
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            // 没取到自定义的就是要默认的
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            // 创建一个baseContext,application中attachBaseContext的就是这个baseContext
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            // 调用mInstrumentation的newApplication创建Application
            app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        ...
        return app;
    }

内部是反射创建,就不对贴代码了

// Instrumentation#newApplication
static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
}
// Application#attach
final void attach(Context context) {
        // 这里就是开始创建的baseContext,所以在Application的attachBaseContext内调用getApplicationContext会返回空
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

然后会处理启动第一个Activity的消息去启动第一个Activity。

上一篇下一篇

猜你喜欢

热点阅读