插件化专题

插件化Activity&Receiver组件

2017-08-20  本文已影响0人  丢底很远

插件化框架实现:基于kotlin的插件化框架

插件化组件的问题

Activity启动流程

ActivityLaunch.png

插件化Activity的解决方案

AMS

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    // ActivityMonitors 相关 ...
    
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        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) {
    }
    return null;
}
static public IActivityManager getDefault() {
   return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        IActivityManager am = asInterface(b);
        return am;
    }
};

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
public interface IActivityManager extends IInterface {
    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
            ProfilerInfo profilerInfo, Bundle options) throws RemoteException;

    // .... 其他接口方法的定义
}

插件Activity -> 宿主Activity

// 创建一个这个对象的代理对象, 然后替换这个字段, 让我们的代理对象帮忙干活
Class<?> iActivityManagerInterface = Class.forName("android.app.IActivityManager");
Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
        new Class<?>[] { iActivityManagerInterface }, new IActivityManagerHandler(rawIActivityManager));
mInstanceField.set(gDefault, proxy);

宿主Activity -> 插件Activity

那怎么完成宿主Activity -> 插件Activity的转换呢?

AMS 版本差异

Android 4.x

Android 2.x

private static IActivityManager gDefault;

static public IActivityManager getDefault() {
    if (gDefault != null) {
        //if (Config.LOGV) Log.v(
        //    "ActivityManager", "returning cur default = " + gDefault);
        return gDefault;
    }
    IBinder b = ServiceManager.getService("activity");
    if (Config.LOGV) Log.v("ActivityManager", "default service binder = " + b);
    gDefault = asInterface(b);
    if (Config.LOGV) Log.v("ActivityManager", "default service = " + gDefault);
    return gDefault;
}

Instrumentation

插件Activity -> 占坑Activity

占坑Activity -> 插件Activity

Instrumentation版本差异

API <= 15

public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, android.os.Bundle options) { ... }

API > 15

public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, android.os.Bundle options) { ... }

Hook Application & Activity startActivity

开源实现

DroidPlugin

VirtualAPK

Replugin

插件Broadcast Receiver的处理

上一篇下一篇

猜你喜欢

热点阅读