Android应用程序启动流程之从startActivity开始

1.简介:

Android系统中,应用程序是由框架创建的。通过startAcitivty函数可以启动一个应用程序,那么,startActivity到底做了些什么,以至于这样一个简单的几行代码就能调用起一个应用程序。本节分析startActivity的执行流程。

2.从Activity的startActivity开始:

当调用startActivity函数时,通过Android Binder机制, 调用到ActivityManagerService.再由ActivityManagerService去创建Java层的Process。
并且最终通过Zygote的fork去真正的创建出一个进程,当然,这个进程可以在adb终端使用ps命令列出来。

当点击一个桌面app图标时,会调用startActivityForResult,然后,会调用到Instrumentation.execStartActivity,并且最终调用到ActivityMangerService的startActivity中,整个流程如下:

 2.1 startActiivy时序图如下:

这样,代码就进入到ActivityManagerService中了,如下图:

可见,ActivityStack对activity进行了管理。

在1.9startSpecificActivityLocked中,会判断app创建没有,如果创建了,就调用

realStartActivityLocked,

否则,就会调用startProcessLocked。

2.2 分支一:realStartActivityLocked函数分析:

最关键的就是:

app.thread.scheduleLaunchActivity

方法的调用。这个app.thread类型是

IApplicationThread

所以,这里通过Binder调用到了ApplicationThreadNative的scheduleLaunchActivity,然后,又调用到了ActivityThread的“scheduleLaunchActivity”。

ActivityThread的scheduleLaunchActivity方法:

queueOrSendMessage(H.LAUNCH_ACTIVITY, r);   ->

    mH.sendMessage(msg);

->

H.handleMessage()中,有:

case LAUNCH_ACTIVITY: {
     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
     ActivityClientRecord r = (ActivityClientRecord)msg.obj;

     r.packageInfo = getPackageInfoNoCheck(
                     r.activityInfo.applicationInfo, r.compatInfo);
     handleLaunchActivity(r, null);
     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}


handleLaunchActivity方法调用了

performLaunchActivity

,在这个方法中,创建了Activity(终于,Activity创建):

//performLaunchActivity方法的实现:
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } 

        ......

        Application app = r.packageInfo.makeApplication   

        ......

        activity.attach

        ......

        mInstrumentation.callActivityOnCreate(activity, r.state);

这样,通过mInstrumentation 创建了Activity,并且执行attach后,再执行

callActivityOnCreate

就进入到Activity的OnCreate生命周期了。

2.3 分支二:startProcessLocked的执行

在执行到startProcessLocked时,代码由ActivityStack进入到ActivityManagerService中,继续执行,如下图:

在Process.java中,有

            argsForZygote.add("--runtime-init");
            argsForZygote.add("--setuid=" + uid);
            argsForZygote.add("--setgid=" + gid);

            ......
    
            zygoteSendArgsAndGetResult(argsForZygote)

 openZygoteSocketIfNeeded函数的实现:

try {
                sZygoteSocket = new LocalSocket();

                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, 
                        LocalSocketAddress.Namespace.RESERVED));

                sZygoteInputStream
                        = new DataInputStream(sZygoteSocket.getInputStream());

                sZygoteWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    sZygoteSocket.getOutputStream()),
                            256);

                Log.i("Zygote", "Process: zygote socket opened");

                sPreviousZygoteOpenFailed = false;
                break;
            } catch (IOException ex) {
                ......
            }

分析:

创建一个LocalSocket sZygoteSocket,作为client通过调用sZygoteSocket.connect 去连接socket,而作为服务端的socket,就是在Zygote初始化时在runSelectLoop中进行监听的套接字,然后,在Zygote中去真正地用fork创建进程。

参见:

Android系统的心脏-Zygote进程如何fork一个新的应用进程

 这样,进程就创建好了。

进程创建好之后,代码回到Process.java中,继续执行。保存进程状态,然后,去创建ActivityThread。(在Process.start时,就将ActivityThread这个类名传递过来了)。

3. ActivityThread:

我们继续分析Application的创建过程(即“分支二:startProcessLocked的执行”的继续执行)

在ActivityThread的main函数中,主要功能:

1)创建Thread;并调用attach方法;

2)进行Application的attach;

3)进行Handler的创建和message的处理;

4)AsyncTask的初始化。

3.1 ActivityThread中的main函数

直接看ActivityThread中的main函数:

public static void main(String[] args) {

        ......

        Looper.prepareMainLooper();

        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        AsyncTask.init();

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();

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

 thread.attach()的实现:

IActivityManager mgr = ActivityManagerNative.getDefault();
    mgr.attachApplication(mAppThread);

3.2 attachApplication方法的执行序列(通过Binder机制实现):

1) 从Client端到Server端:

注意,这里的mgr是ActiivtyManagerProxy的实例,而ActiivtyManagerProxy是Binder机制中的Client端,是服务端AMS(ActivityManagerService)的代理。

再通过Binder IPC机制调用到AMS的对应的方法中,调用序列如下:

1. client端:

ActivityManagerNative.getDefault://获取ActivityManagerProxy

ActivityManagerProxy.attachApplication -> mRemote.transact, 如下:

    public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

这样,通过Binder机制就执行到了ActivityManagerService中了。

2. server端:

在ActivityManagerNative中,有对ATTACH_APPLICATION_TRANSACTION的处理(这时,已经是在Service执行这个case了):

case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }

而这里的attachApplication方法就在ActivityManagerService中有实现,代码如下:

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

调用到server端:ActivityManagerNative  ->ActivityManagerService。

继续AMS的attachApplication的分析,就执行到AMS中的对应的

attachApplicationLocked

方法中了,这个方法非常重要,接下来分析一下。

2)AMS中attachApplicationLocked方法的分析:

在attachApplicationLocked方法中,关键调用了下面这个方法:

thread.bindApplication(processName, appInfo, providers,...)//省略若干参数

说明:

这里的thread是IApplicationThread类型,而且thread是Client端,真正类型是ApplicationThreadProxy,即服务端的代理。而这个ApplicationThreadProxy是在ApplicationThreadNative中定义的。

所以,我们来分析ApplicationThreadProxy的bindApplication方法的实现。

继续分析,ApplicationThreadProxy的bindApplication方法的实现:

public final void bindApplication(String packageName, ApplicationInfo info,
            ......) throws RemoteException {

        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeString(packageName);
        info.writeToParcel(data, 0);

        ...... //都是data.write方法
        
        
        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
}

mRemote.transact最终调用到ApplicationThreadNative中,即Service端。

3)服务端对BIND_APPLICATION_TRANSACTION的处理:

mRemote是IBinder类型,而真正的实例是ActivityThread。

原因如下:

ApplicationThreadNative是抽象类,无法实例化;

ActivityThread是继承自ApplicationThreadNative的具体类;

所以,mRemote其实是ActivityThread的实例。

然后,就是BIND_APPLICATION_TRANSACTION的处理:

mRemote.transact通过binder机制,调用到ApplicationThreadNative中去处理。

代码如下:

case BIND_APPLICATION_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            String packageName = data.readString();
            ApplicationInfo info =
                ApplicationInfo.CREATOR.createFromParcel(data);
            
            ......
            
            bindApplication(packageName, info,
                            providers, testName, profileName, profileFd, autoStopProfiler,
                            testArgs, testWatcher, testMode, openGlTrace, restrictedBackupMode,
                            persistent, config, compatInfo, services, coreSettings);
            return true;
        }

这里的bindApplication是在ApplicationThread中实现的。前面已经分析过,ApplicationThread是ApplicationThreadNative的子类。所以在ApplicationThreadNative中的代码调用,其实就是ApplicationThread的代码的执行。

4)ApplicationThread的bindApplication方法:

在ApplicationThread的bindApplication方法中,最后一条语句

queueOrSendMessage(H.BIND_APPLICATION, data);

发送了message,在H 这个handler类中,对message的处理如下:

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;

接着,我们看

handleBindApplication

5) handleBindApplication的分析:

好像看到一些曙光了。再次说明一下,我们分析这部分代码的目的是:为了分析清楚一个App是如何被创建和初始化的。也就是说,Application的onCreate函数是如何被执行的。

在handleBindApplication中,关键点如下:

1. mInstrumentation的创建;

 mInstrumentation = new Instrumentation(); //如果已经创建,就不需要new了

2. Application的创建;

Application app = data.info.makeApplication(data.restrictedBackupMode, null);

3. 通过mInstrumentation的

callApplicationOnCreate

来启动App:

        mInstrumentation.callApplicationOnCreate(app);

Instrumentation.callApplicationOnCreate的实现:

到了这里,只需要一句代码即可:

public void callApplicationOnCreate(Application app) {
        app.onCreate();
}

这样,就调用到了app的onCreate()方法了。

至此,整个分析流程结束。

4. 总结:

1. 一系列的startActivity的调用;

2. AMS(ActivityManagerService)相关的关键组件:

ActivityManager //可以认为是对ActivityManagerProxy的封装

ActivityManagerProxy //作为客户端;

ActivityManagerNative //抽象类,无法实例化;

ActivityManagerService //继承自ActivityManagerNative,具体类,作为服务端;

3. ApplicationThread相关的关键的组件:

ApplicationThreadProxy //作为客户端;

ApplicationThreadNative //抽象类,无法实例化;

ApplicationThread //继承自ApplicationThreadNative,具体类,作为服务端;

4. Instrumentation //Activity和Application的启动,都要由它来触发。

可见,从binder的角度来看,AMS和ApplicationThread的组件架构几乎一样。这是Android系统服务中典型的服务实现方式。


  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值