首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用DexClassLoader动态替换活动或服务

如何使用DexClassLoader动态替换活动或服务
EN

Stack Overflow用户
提问于 2010-03-26 06:04:59
回答 1查看 12.5K关注 0票数 18

我正在尝试做一些类似于这个stackoverflow posting的事情。我想要做的是从SD卡中读取活动或服务的定义。为了避免清单权限问题,我在.apk中创建了此活动的外壳版本,但尝试在运行时将其替换为SD卡上驻留的同名活动。不幸的是,我可以使用DexClassLoader从SD卡加载活动类定义,但原始的类定义是被执行的类定义。有没有一种方法可以指定新的类定义替换旧的类定义,或者在不实际提供包中所需活动的情况下避免清单权限问题的任何建议?代码示例:

代码语言:javascript
复制
    ClassLoader cl = new DexClassLoader("/sdcard/mypath/My.apk",
            getFilesDir().getAbsolutePath(),
            null,
            MainActivity.class.getClassLoader());

    try {
        Class<?> c = cl.loadClass("com.android.my.path.to.a.loaded.activity");
        Intent i = new Intent(getBaseContext(), c);
        startActivity(i);
    }
    catch (Exception e) {

除了启动/sdcard/mypath/My.apk中指定的com.android.my.path.to.a.loaded.activity外,它还会启动静态加载到项目中的活动。

EN

回答 1

Stack Overflow用户

发布于 2013-04-08 11:21:19

通过DexClassLoader启动一个活动将是非常棘手的,因为您没有安装APK,所以没有任何东西可以处理您的意图。

您应该在您的平台APK中拥有相同的activity类,并在AndroidManifest.xml中声明它。然后,您应该将当前ClassLoader更改为所需的DexClassLoader。因此,它将启动您的插件APK。(注意:平台apk是指手机中已经安装的app,插件apk是指保存在SD卡中的apk文件。)

平台的应用程序应该如下所示:

代码语言:javascript
复制
public static ClassLoader ORIGINAL_LOADER;
public static ClassLoader CUSTOM_LOADER = null;

@Override
public void onCreate() {
    super.onCreate();
    try {
        Context mBase = new Smith<Context>(this, "mBase").get();

        Object mPackageInfo = new Smith<Object>(mBase, "mPackageInfo")
                .get();
        //get Application classLoader
        Smith<ClassLoader> sClassLoader = new Smith<ClassLoader>(
                mPackageInfo, "mClassLoader");
        ClassLoader mClassLoader = sClassLoader.get();
        ORIGINAL_LOADER = mClassLoader;

        MyClassLoader cl = new MyClassLoader(mClassLoader);
        //chage current classLoader to MyClassLoader
        sClassLoader.set(cl);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

class MyClassLoader extends ClassLoader {
    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    @Override
    public Class<?> loadClass(String className)
            throws ClassNotFoundException {
        if (CUSTOM_LOADER != null) {
            try {
                Class<?> c = CUSTOM_LOADER.loadClass(className);
                if (c != null)
                    return c;
            } catch (ClassNotFoundException e) {
            }
        }
        return super.loadClass(className);
    }
}

有关更多代码,请访问https://github.com/Rookery/AndroidDynamicLoader

我正在阅读Android源代码,以便找到一种更优雅的方法来实现此功能。如果你有任何想法,请随时联系我。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2519760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档