Android应用程序的启动

2020-04-26  本文已影响0人  G_Freedom

Android源码版本9.0

应用程序的启动

从手机屏幕点击APP图标起,APP的启动就已经开始了
首先:
执行java首次启动都要执行的main方法开始
Android main方法存在于ActivityThread中,也就是说启动应用都要从ActivityThread的main方法开始

##ActivityThread
public static void main(String[] args) {
        ...
        Looper.prepareMainLooper(); //1
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        ActivityThread thread = new ActivityThread();  //2
        thread.attach(false, startSeq); //3
        ...
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
}

说一下几个比较重要的方法 ->

接下来看一下具体连接了什么

##ActivityThread
private void attach(boolean system, long startSeq) {
        ...
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();  //1
            try {
                mgr.attachApplication(mAppThread, startSeq);  //2
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        } else {
            ...
        }
        ...
}

IActivityManager具体执行方法是在ActivityManagerService,这里让Application去和AMS连接是为了APP和系统绑定,更好的方便管理当前APP。

##ActivityManagerService
public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            //获取pid
            int callingPid = Binder.getCallingPid();  //1
            //获取uid
            final int callingUid = Binder.getCallingUid();  //2
            final long origId = Binder.clearCallingIdentity();
            //连接Application
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);  //3
            Binder.restoreCallingIdentity(origId);
        }
}

attachApplication是AMS中的一个方法。

##ActivityManagerService
private final boolean attachApplicationLocked(IApplicationThread thread,
                                                  int pid, int callingUid, long startSeq) {
        ProcessRecord app;  //1
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);  //2
            }
        } 
        ...
        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, isAutofillCompatEnabled);   //3
        } else {
            //Application 绑定到当前线程
            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, isAutofillCompatEnabled);  //4
        }
        ...
        //检测最可见的Activity是否在运行进程中等待,如果再则创建Activity
        if (mStackSupervisor.attachApplicationLocked(app)) {  //5
            didSomething = true;
        }
        ...
}

总结:App的启动从应用图标被点击开始,首先执行的是ActivityThread中的main方法。
1、创建出进程唯一的UI线程,并启动它的消息队列。
2、获取IActivityManager也就是ActivityManagerService请求系统进程接口,通过AIDL实现进程间通信,作用是APP连接系统进程,方便管理当前APP。这样就完成了系统和应用进程的绑定。

绑定Application

##ActivityThread.ApplicationThread
public final void bindApplication(String processName...boolean autofillCompatibilityEnabled) {
        ...
        setCoreSettings(coreSettings);
        AppBindData data = new AppBindData();
        data.processName = processName;  //当前进程名字
        data.appInfo = appInfo;     //app信息
        data.providers = providers; //providers
        ...
        //最后使用Handler发送消息,并携带AppBindData数据
        sendMessage(H.BIND_APPLICATION, data);
}

在bindApplication中,会把传入的一系列参数封装成一个AppBindData对象,然后通过Handler把这个对象发送出去。H是ActivityThread中的内部类,是Handler的子类。

##ActivityThread.H
public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            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;
            ...
        }
        ...
}

handleMessage方法是H中的方法,主要是用来处理消息。

##ActivityThread 
private void handleBindApplication(AppBindData data) {
        ...
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);  //1
        ...
        Application app;
        ...
        //创建Application
        app = data.info.makeApplication(data.restrictedBackupMode, null);  //2
        ...
        //调用Application中的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);  //3
        ...
}

##LoadedApk
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        ...
        try {
            java.lang.ClassLoader cl = getClassLoader();
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);//2
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        ...
}
            
##Instrumentation
public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);//2
        return app;
}
public void callApplicationOnCreate(Application app) {
        app.onCreate();//3
}

总结:创建Application步骤
1、获取系统分配的pid和uid。
2、通过IApplicationThread请求当前进程。
3、发送消息把创建逻辑切换到UI线程中,如果现在可能是在其他线程的话。
4、通过类加载器和反射创建Application并绑定一个上下文环境。
5、最后执行Application中的onCreate方法完成整个Application的创建并初始化。

创建Activity

##ActivityStackSupervisor
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        ...
        if (realStartActivityLocked(activity, app,
                top == activity /* andResume */, true /* checkConfig */)) {
            didSomething = true;
        }
        ...
}

realStartActivityLocked,真正开始Activity的创建。

##ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                                          boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        // 创建启动Activity
        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                System.identityHashCode(r), r.info,
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                profilerInfo));  //添加LaunchActivityItem的回调
        // Set desired final state.
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
        // 通过生命周期管理对象ClientLifecycleManager,来管理Activity的生命周期状态
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...
        return true;
}

##ClientLifecycleManager
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        //ClientTransaction是个javabean 实现了Parcelable 序列化。
        //schedule()方法内部,会回调到ActivityThread.ApplicationThread的scheduleTransaction()方法
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
}

##ActivityThread.ApplicationTread
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        //ActivityThread.this 指的是父类ClientTransactionHandler
        ActivityThread.this.scheduleTransaction(transaction);
}

##ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        //发送Handler消息
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

执行这一系列的方法后,会发送一条消息,在ActivithThread中处理。

##ActivityThread.H
public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case EXECUTE_TRANSACTION:
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                //开始执行
                mTransactionExecutor.execute(transaction);
                if (isSystem()) {
                    // Client transactions inside system process are recycled on the client side
                    // instead of ClientLifecycleManager to avoid being cleared before this
                    // message is handled.
                    transaction.recycle();
                }
                // TODO(lifecycler): Recycle locally scheduled transactions.
                break;
                ...
        }
        ...
}

##TransactionExecutor
public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
        executeCallbacks(transaction);  //1
        executeLifecycleState(transaction);  //5
        mPendingActions.clear();
        log("End resolving transaction");
}
public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();  //2
        ...
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);  //3
            ...
            item.execute(mTransactionHandler, token, mPendingActions);  //4
            ...
        }
}

##LaunchActivityItem
@Override
public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ...
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//5
        ...
}
##ActivityThread
public Activity handleLaunchActivity(ActivityClientRecord r,
                                         PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        //开始执行Activity的创建
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;   //1
        ...
        ContextImpl appContext = createBaseContextForActivity(r);   //2
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();   //3
            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);  //4
           ...
        } catch (Exception e) {
           ...
        }
        ...
        //调用Activity的OnCreate()方法
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);   //5
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);   
        }
        ...
        return activity;
}

##Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
       
        activity.performCreate(icicle);
        postPerformCreate(activity);
}

##Activity
final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        //onCreate 生命周期方法被调用
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
}

总结:Activity的创建
1、前期先做好Activity创建前的一系列相关环境配置
2、依然是通过ActivityThread的Handler把需要创建Activity的消息发送过去并把对应的申请放入到ClientTransaction队列当中。
3、最终消息会回到ActivityThread的handleLaunchActivity方法中去处理,在里面完成Activity的创建步骤。

上一篇 下一篇

猜你喜欢

热点阅读