在真正分析插件化技术前,我们必须了解一些必要的关于Android四大组件的相关知识。

以Activity为例,我们需要了解Activity启动过程,才能有效的进行Hook实现插件化。

以Android 8.1为例

我们启动一个Activity通常会使用startActivity方法,但是在Activity内部最终都会调用startActivityForResult方法

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

在这个方法的内部实际是调用Instrumentation类的execStartActivity方法。

在这里我们遇到了三个非常重要的类。

  1. Instrumentation : 随着Activity内部会持有一个对Instrumentation的引用,
  2. ActivityThread : 主线程,在app启动的时候创建的,代表了Android应用程序,里面包含了Main函数
  3. ApplicationThread : App端在system进程的代理类(涉及到Binder机制)

接着会调用Instrumentation内部的execStartAcivitiesAsUser方法

    public void execStartActivitiesAsUser(Context who, IBinder contextThread,            IBinder token, Activity target, Intent[] intents, Bundle options,            int userId) {        IApplicationThread whoThread = (IApplicationThread) contextThread;        ......        try {            .......            int result = ActivityManager.getService()                .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,                        token, options, userId);            checkStartActivityResult(result, intents[0]);        } catch (RemoteException e) {            throw new RuntimeException("Failure from system", e);        }    }

然后我们进入ActivityManager内部,getService实际返回的是一个单例对象,持有AMS在app端的远程代理对象。

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

所以从这里就从app进程进入到system进程。

AMS里的代码很多,逻辑非常复杂,只要知道AMS会对传递过来的Intent进行检查,如果需要启动的Activity没有在manifest里申明,就会把错误码返回给Instrumentation,从而Instrumentation就会抛出经典的ActivityNofFoundException异常。

如果通过AMS的检查,那么会回调ApplicationThread的scheduleLauncherActivity方法

        @Override        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,                int procState, Bundle state, PersistableBundle persistentState,                List pendingResults, List pendingNewIntents,                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {            updateProcessState(procState, false);            ActivityClientRecord r = new ActivityClientRecord();            ......            sendMessage(H.LAUNCH_ACTIVITY, r);        }

给H发送了一个LAUNCH_ACTIVITY的消息

                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

就正式开始了Activity的启动过程。

从以上的分析,我们是无法启动一个没有manifest注册的Activity,但是插件化技术却可以绕过AMS的检查达到这样一个目的。

更多相关文章

  1. Android理解:IntentService
  2. 使用 Eclipse 调试 android 程序(debug 方法)
  3. 个人android工具包——androidkit更新
  4. Android中AppWidget加载流程(二)
  5. Android(安卓)x86模拟器Intel Atom x86 System Image配置与使用
  6. android语言三
  7. Android(安卓)Intent传递对象的两种方法(Serializable,Parcelabl
  8. android+面试题
  9. Android(安卓)Java 线程池 ThreadPoolExecutor源码篇

随机推荐

  1. Android Studio Error : Instant Run req
  2. 在Android中实现全屏显示的方法
  3. Mac完整卸载Android Studio的方法
  4. 【Android 设计】:模式_ Android新特性
  5. ListView的一些属性
  6. android adb bundle下载
  7. Android之父Andy Rubin:生而Geek
  8. Android Instrumentation Test
  9. Android 7.0 SystemUI(2)--Multi-Window
  10. Android 读取U盘或SD卡中的所有.txt文件