返回顶部
首页 > 资讯 > 移动开发 >一文带你看懂Android Application启动流程是怎样的
  • 243
分享到

一文带你看懂Android Application启动流程是怎样的

2024-04-02 19:04:59 243人浏览 独家记忆
摘要

基于Android11-api30 总览 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也

基于Android11-api30

总览

  • 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也传递到AMS进程,请求远程调用通知AMS应用进程想要创建Application,此时AMS为服务端
  • AMS收到消息,请求调用applicationThread的远程接口,此时AMS为客户端
  • applicationThread收到AMS的请求,通过Handler发起创建Application的处理任务,后面就没有远程接口调用了
  • 通过反射创建Application的实例,通过Instrumentation启动Application的onCreate方法

详细流程分析

从 ActivityThread.java 的main方法开始看;


public static void main(String[] args) {
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(system=false, startSeq);//1
    ...
}

进入attach方法;


if(!system){
    final IActivityManager mgr = ActivityManager.getService();
    try {
        mgr.attachApplication(mAppThread, startSeq);//1
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

非系统应用流程,根据 getSeervice和捕获的RemoteException可以断定,此处在使用Binder进行远程接口调用。
转身看下mAppThread是什么?


final ApplicationThread mAppThread = new ApplicationThread();

private class ApplicationThread extends IApplicationThread.Stub {
    //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等
    public final void schedule*
    
    //TODO 关键方法
    public final void bindApplication(some args){}//1
    
    //一堆dump方法,比如dumpMemory、dumpActivity等
    
}

可以看到,ApplicationThread是一个实现了远程接口的Binder客户端,内部封装实现了很多远程接口。不过这个客户端什么时候连接的服务器还未可知,没有找到bindService关键字,反正此时应该已经连接上对应的Service了。应该是在RuntimeInit.java类中进行应用进程启动时启动的。

回来看下前一步服务的实例IActivityManager.attachApplication()内部的实现。

先获取AMS的实例,此处获取AMS实例代码跟Activity启动流程中一致


public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

…获取到AMS的Binder后,继续查看ActivityManagerService.java中的attachApplication方法


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

单例获取AMS实例,AMS服务在系统启动就已经注册到ServiceManager了,此处直接去获取Binder实例就行,ServiceManager以Binder池的方式管理注册的Server。

AMS的attachApplication方法中进入到attachApplicationLocked方法,捡能看懂的代码看,跟着thread参数查看代码。


private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

    try {
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);//1
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        mProcessList.startProcessLocked(app,
                new HostingRecord("link fail", processName),
                ZYGoTE_POLICY_FLAG_EMPTY);
        return false;
    }

    final ActiveInstrumentation instr2 = app.getActiveInstrumentation();

    if (instr2 != null) {//2
        thread.bindApplication(processName, appInfo, providerList,
                instr2.mClass,
                profilerInfo, instr2.mArguments,
                instr2.mWatcher,
                instr2.mUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !nORMalMode, app.isPersistent(),
                new Configuration(app.getWindowProcessController().getConfiguration()),
                app.compat, getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked(),
                buildSerial, autofillOptions, contentCaptureOptions,
                app.mDisabledCompatChanges);
    } else {
        thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                null, null, null, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.isPersistent(),
                new Configuration(app.getWindowProcessController().getConfiguration()),
                app.compat, getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked(),
                buildSerial, autofillOptions, contentCaptureOptions,
                app.mDisabledCompatChanges);
    }

}

先给ApplicationThread这个Binder上个死亡代理,根据这个死亡代理应该可以找到对应的Service是如何重新启动的,感兴趣可以继续深入,咱们继续往下走。
此处调用到thread.bindApplication接口,前面咱们查看ApplicationThread时有看到,直接切入。


private class ApplicationThread extends IApplicationThread.Stub {
    //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等
    public final void schedule*
    
    //TODO 关键方法
    public final void bindApplication(some args){
        AppBindData data = new AppBindData();
        ...一堆参数
        sendMessage(H.BIND_APPLICATION, data);//1
    }
    
    //一堆dump方法,比如dumpMemory、dumpActivity等
    
}

到达咱们Android开发工程师比较熟悉的点了,封装了一堆参数后,通过H这个Handler对象发了一条BIND_APPLICATION消息,咱们看看这条消息去哪了,直接跟进BIND_APPLICATION这个消息的捕捉位置。


//消息分发
class H extends Handler{
    public void handleMessage(Message msg){
        swich(msg.what){
            case BIND_APPLICATION: 
                AppBindData data = (AppBindData)msg.obj;
                handleBindApplication(data);//1
                break;
            ...省略
        }
    }
}

进入消息分发处理方法,这个方法比较长,注意阅读能看懂的代码,不求甚解,跟踪data的处理。


private void handleBindApplication(AppBindData data) {
    //各种初始化,比如进程名,应用名,AsyncTask线程池的配置,时区,网络发现
    
    //Context的初始化
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    
    try {
        final ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)//1
            cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    } catch (Exception e) {
        throw new RuntimeException(
            "Unable to instantiate instrumentation "
            + data.instrumentationName + ": " + e.toString(), e);
    }
    
    final ComponentName component = new ComponentName(ii.packageName, ii.name);
    mInstrumentation.init(this, instrContext, appContext, component,//1
            data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
            
    ...
    Application app;
    app = data.info.makeApplication(data.restrictedBackupMode, null);//2

    mInstrumentation.onCreate(data.instrumentationArgs);
    mInstrumentation.callApplicationOnCreate(app);//3
}

通过反射实例化mInstrumentation对象,该对象为Android系统组件的管家,目前看可以控制Application和Activity的生命周期。

创建Application对象,进去看下创建的代码


//LoadApk.java #makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
    Instrumentation instrumentation){
    ...
    app = MactivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//1
    appContext.setOuterContext(app);
    ...
}

//Instrumentation.java #newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);//2
    app.attach(context);//首先回调attacHBaseContext方法
    return app;
}

//AppComponentFactory #instantiateApplication
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
        @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();//3
}

可以看出最后还是通过反射初始化了Application。

最后通过mInstrumentation对象完成Application类的onCreate方法的调用。


mInstrumentation.callApplicationOnCreate(app);//1

//Instrumentation.java #callApplicationOnCreate
public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

到此这篇关于一文带你看懂Android Application启动流程是怎样的的文章就介绍到这了,更多相关Android Application 启动流程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一文带你看懂Android Application启动流程是怎样的

本文链接: https://lsjlt.com/news/154906.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文带你看懂Android Application启动流程是怎样的
    基于Android11-API30 总览 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也...
    99+
    2024-04-02
  • CentOS6 启动流程是怎样的
    CentOS6 启动流程是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。我们在使用Linux操作系统的时候,我们只需按下电源键,等待,然后输入账户和密码就可以使用Linu...
    99+
    2023-06-16
  • Ubuntu启动流程是怎样的
    这篇文章主要介绍“Ubuntu启动流程是怎样的”,在日常操作中,相信很多人在Ubuntu启动流程是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Ubuntu启动流程是怎样的”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-17
  • CentOS系统启动流程是怎样的
    这篇文章给大家介绍CentOS系统启动流程是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. CentOS5POST开机自检运行CMOS中的BIOS程序,加载第一个启动磁盘的Bootloader由Bootloa...
    99+
    2023-06-28
  • Linux系统启动流程是怎么样的
    这篇文章主要为大家展示了“Linux系统启动流程是怎么样的”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux系统启动流程是怎么样的”这篇文章吧。linux启动时我们会看到许多启动信息,Li...
    99+
    2023-06-27
  • Linux中arm64多核启动流程是怎样的
    今天小编给大家分享一下Linux中arm64多核启动流程是怎样的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Kernel ...
    99+
    2023-06-28
  • PostgreSQL启动恢复流程框架是怎么样的
    小编给大家分享一下PostgreSQL启动恢复流程框架是怎么样的,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!以上是“Postg...
    99+
    2024-04-02
  • Linux操作系统启动流程是怎么样的
    这篇文章主要为大家展示了“Linux操作系统启动流程是怎么样的”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux操作系统启动流程是怎么样的”这篇文章吧。Linux操作系统启动流程02 Ce...
    99+
    2023-06-15
  • Java 图解Spring启动时的后置处理器工作流程是怎样的
    探究Spring的后置处理器 本次我们主要探究invokeBeanFactoryPostProcessors();后面的代码下次再做解析; 入口代码refresh() Annot...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作