Android动态部署三:如何从插件apk中启动Activity(-)

本文详细分析了Android动态部署过程中,如何从插件APK中启动Activity。通过理解Activity的启动流程,关注关键点如Intent、ClassLoader、Stub Activity,探讨了如何重写Instrumentation以实现动态加载非安装APK中的组件。文中还提供了实现思路和后续步骤的预告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.csdn.net/ximsfei/article/details/50926406

github地址:https://github.com/ximsfei/DynamicDeploymentApk

在上一篇文章:APK安装及AndroidManifest.xml解析流程分析中分析了如何通过adb 命令安装apk,以及源码中apk解析的流程,根据这部分源码,我们可以自己去解析AndroidManifest.xml或者直接porting这部分源码,这样解析出来的信息会更完整,对后续的开发更有帮助;

接下来我们就来分析一下从Activity中startActivity的流程(Fragment等调用startActivity方法的流程类似,读者可以对照着这篇文章自己去看),并且我会重点描述一下,在实现动态部署框架时所需要关注的点。

Activity启动流程

startActivity(new Intent(this, TargetActivity.class));

在Activity中,很简单的一行代码,就可以跳转到TargetActivity了,下图就是调用这行代码后的时序图:
startActivity
其中红色标注的是在看代码的过程中需要关注的。

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    ...
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
    ...
}

首先我们来看,调用startActivity后,会根据不同参数调用startActivityForResult方法,在startActivityForResult方法中又会调用mInstrumentation的execStartActivity方法,在Activity的源码中我们看到mInstrumentation是在attach方法中初始化的

final void attach(Context context, ActivityThread aThread,
       Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    ...
    mInstrumentation = instr;
    ...
}

Instrumentation.java

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options, UserHandle user) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ...
    try {
        ...
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

在execStartActivity中会通过binder机制调用到AMS中的startActivity方法,这里的whoThread可以简单的理解为ActivityThread$ApplicationThread对象,以及intent中携带了TargetActivity的信息。

ActivityManagerService.java

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,                                          
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值