标签: dexclassloader

如何在自定义数据目录上执行APK?

我想知道Parallel Space应用程序如何复制和执行其他应用程序而无需复制其APK或在Playstore上的其他应用程序下运行它们(例如:"com.whatever.name-of-duplicated-app").

在研究了他们的AndroidManifest.xml,在/ data/data /上创建的文件夹以及设备上的日志之后,我得到的唯一结论是,Parallel Space能够以某种方式执行来自其他APK的代码,但它会映射数据目录这些应用程序进入自己的数据目录.

证据:

  1. 目录创建如下:/data/data/com.lbe.parallel.intl/parallel_intl/0/whatever-package-name-you-cloned
  2. 每个重复的应用程序执行都以其一个代理活动的新任务开始,然后以某种方式重复的应用程序取代新创建的进程.

最初,我认为它与DexClassLoader/PathClassLoader API有关,但我无法继续进行调查.我也看到了一些这样的问题,一个,但它似乎并不如此.

android dexclassloader

12
推荐指数
1
解决办法
1480
查看次数

为什么Android类加载器允许从另一个包反射访问包私有类的公共字段?

似乎Android应用程序类加载器允许反射性地获取对public static包私有类的字段的引用,甚至来自不同的包(比上面定义的类中的那个),而Sun JDK类加载器例如没有.

更具体地说,给定以下类定义:

package org.example.a

class PackagePrivateClass {
    public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator();
}
Run Code Online (Sandbox Code Playgroud)

以下代码在一个单独的包中:

package org.example.b

public class TestClass {
    public void testMethod() {
        final Class classRef = Class.forName("org.example.a.PackagePrivateClass");
        final Field creatorFieldRef = classRef.getField("CREATOR");
        creatorFieldRef.get(null);  // throws here (unless on Android)
    }
}
Run Code Online (Sandbox Code Playgroud)

在Sun JVM上执行时,它会抛出IllegalAccessException最后一行:

java.lang.IllegalAccessException: Class org.example.b.TestClass can not access a member of class org.example.a.PackagePrivateClass with modifiers "public static final"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
...
Run Code Online (Sandbox Code Playgroud)

但是,当在Android设备(5.1 Lollipop FWIW)上运行时,它会在不抛出的情况下执行,并creatorFieldRef.get(null)实际返回对该CREATOR字段的有效引用.

我的问题是:为什么会这样?它是Android类加载器的错误还是功能?(或者,如果适用的话,我的例子中出了什么问题?)

java android classloader dexclassloader

10
推荐指数
1
解决办法
270
查看次数

如何修复“dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:134)”

升级到64位armeabi库,打包打包发布到googleplay后,在googleplay崩溃报告页面遇到如下问题:

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:3982)
  at android.app.ActivityThread.access$2300 (ActivityThread.java:273)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2050)
  at android.os.Handler.dispatchMessage (Handler.java:112)
  at android.os.Looper.loop (Looper.java:216)
  at android.app.ActivityThread.main (ActivityThread.java:7625)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:524)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:987)
Caused by: java.lang.ClassNotFoundException: 
  at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:134)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:379)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:312)
  at android.app.AppComponentFactory.instantiateReceiver (AppComponentFactory.java:84)
  at android.support.v4.app.CoreComponentFactory.instantiateReceiver (CoreComponentFactory.java:56)
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:3975)
  at android.app.ActivityThread.access$2300 (ActivityThread.java:273)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2050)
  at android.os.Handler.dispatchMessage (Handler.java:112)
  at android.os.Looper.loop (Looper.java:216)
  at android.app.ActivityThread.main (ActivityThread.java:7625)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:524)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:987)
Run Code Online (Sandbox Code Playgroud)

它仅出现在 Android 9 设备上

我在我最小的发布版本应用程序中关闭了 R8。但它看起来和以前一样。问题仍然发生 …

android google-play dexclassloader android-9.0-pie

10
推荐指数
1
解决办法
5793
查看次数

具有DexClassLoader()和用户界面的插件系统

对于一个长期的学生项目,我正在尝试使用插件开发模块化应用程序.具体来说,我们会:

  • 我们可以搜索,更新,删除和运行插件的主应用程序.此主应用程序还将存储插件中的一些数据.

  • 从带有代码和GUI组件的HTTP服务器下载的几个插件.

现在,我有一个主应用程序,它能够从HTTP下载.apk文件,并从此.apk文件中定义的类创建一个新实例.我使用这里描述的方式:http://android-developers.blogspot.fr/2011/07/custom-class-loading-in-dalvik.html使用DexClassLoader()方法.

但是我无法看到如何在插件.apk文件中显示存储为资源的布局(或任何其他GUI组件).例如,我试图通过使用插件类名从主应用程序创建一个Intent,但没有成功:

DexClassLoader cl = new DexClassLoader(...);
Class<?> libClass = cl.loadClass("plugin_classname");
Intent intent = new Intent(this.getApplicationContext(), libClass);
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为Intent未在主应用程序的AndroidManifest.xml中声明.这也在这个其他线程中描述:Android-使用DexClassLoader加载apk文件

这是否意味着绝对没有办法建立这样的"动态"用户界面?更一般地说,这种类型的插件系统可以在Android上完成吗?我应该尝试其他方法吗?

android dexclassloader

8
推荐指数
1
解决办法
1336
查看次数

是不是Android永远不会卸载类?

我们有一个大型的应用程序,总是遇到恐惧方法计数限制.我被要求想方设法让它做得更多,包括支持插件.寻找方法来卸载代码,我跑过JNI提示其说

只有在与ClassLoader关联的所有类都可以进行垃圾回收时,才会卸载类,这种情况很少见,但在Android中并非不可能.

这似乎意味着如果你说,你可以卸载一个插件

  1. DexClassLoader为每个.jar文件使用new ,
  2. 只能通过接口引用来引用插件,并且
  3. 完成后,取消该接口引用的任何副本.

所以,我创建了一个测试用例:

  1. 我创建了几个简单的插件,每个插件使用一个独特的加载器.
  2. ReferenceQueue<ClassLoader>使用该队列创建了一个并创建了对我的两个加载器的弱引用; 我创建/启动了一个无限循环,执行队列.remove()和报告的线程.
  3. 我类似地创建了一个ReferenceQueue<Class<?>>getClass()使用队列创建了对每个插件的弱引用; 我创建/启动了另一个监视类引用队列的线程.
  4. 我创建了一千个1000x1000xARGB_8888位图来彻底强制gc.

我的监控线程似乎工作 - loader2当我loader1以前错误地加载两个插件时,我看到得到gc-ed ;-) - 但是否则我的线程保持沉默,即使在4.3.我可能在这个测试用例中遗漏了一些明显的东西,或者仍然是这样的情况

Dalvik VM目前没有卸载类

正如Google员工faddenAndroid中所说的那样:什么时候系统会卸载类?

android dexclassloader

8
推荐指数
1
解决办法
1618
查看次数

如何使用DexClassLoader从AAR文件动态加载类

我已成功通过以下方式从dex文件动态加载类

enter code here
File file = getDir("dex", 0);
DexClassLoader dexClassLoader = new DexClassLoader("/data/data/com.example.callerapp/files/test.dex", file.getAbsolutePath(), null, getClassLoader());
try {
    Class<Object> _class = (Class<Object>) 
    dexClassLoader.loadClass("com.example.calledapp.test");
    Object object = _class.newInstance();
    Method method = _class.getMethod("function");
    method.invoke(object);
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

但是我想做的是从aar文件动态加载类,如android dev页面所示(DexClassLoader:一个类加载器,它从包含classes.dex条目的.jar和.apk文件中加载类。可以使用执行未作为应用程序一部分安装的代码。)

我在Android Studio中创建了一个库模块(“ testlibrary”),在该库模块中创建了Test.java(我想在调用方应用中动态加载的内容),并通过Gradle Project-> Excute Gradle Task创建了一个aar文件

如何通过dexclassloader在以这种一般方式创建的aar文件中动态加载类?我已通过提供商将aar文件从CalledApp移到CallerApp

还是创建aar文件的过程错误?在运行期间,出现错误消息

02-10 09:43:48.744 16487-16487/com.example.callerapp W/System.err: java.lang.ClassNotFoundException: Didn't find class "com.example.calledlibrary.Test" on path: DexPathList[[zip file "/data/data/com.example.callerapp/files/testlibrary.aar"],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]
02-10 09:43:48.744 16487-16487/com.example.callerapp W/System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
02-10 09:43:48.744 16487-16487/com.example.callerapp W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
02-10 09:43:48.744 …
Run Code Online (Sandbox Code Playgroud)

android dex dexclassloader aar

5
推荐指数
2
解决办法
1644
查看次数

DexClassLoader - 添加功能

我正在使用 DexClassLoader 进行一些测试,看看是否可以使用新功能“更新”我的应用程序。目前我已经有了这个测试方法,它与 testClass 一起使用并运行 test() 方法。我想知道的是,我如何“替换”或“更新”和已经存在的类..?欢迎任何想法或其他建议。

方法:

    public static void loadExtLib(String pathDexFile, Context ctx) {

    String temp = ctx.getDir("temp", 0).toString();


        DexClassLoader classLoader = new DexClassLoader(pathDexFile,
                    temp, null, ctx.getClass().getClassLoader());


          String testClass = "com.mystudio.myapp.TestClass";
          Class<?> libProviderClass = null;
          try {
            libProviderClass = classLoader.loadClass(testClass);
        } catch (ClassNotFoundException e1) {

            e1.printStackTrace();
        }


          try {
            Method m = libProviderClass.getDeclaredMethod("test", null);
            try {
                m.invoke(libProviderClass, null);

            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } …
Run Code Online (Sandbox Code Playgroud)

android dalvik dexclassloader

3
推荐指数
1
解决办法
1375
查看次数

Android Multidex列出所有类

我想使用ApplicationWrapepr方法在我的应用程序中使用multidex,如此处所述https://plus.google.com/104023661970539138053/posts/YTMf8ADTcFg

我使用了--minimal-main-dex选项以及这样的keep文件:

android/support/multidex/ZipUtil.class
android/support/multidex/ZipUtil$CentralDirectory.class
android/support/multidex/MultiDex$V14.class
android/support/multidex/MultiDexExtractor$1.class
android/support/multidex/MultiDexExtractor.class
com/<mypackage>/common/MyApplication.class
com/<mypackage>/common/MyApplicationWrapper.class
com/<mypackage>/common/ui/DashboardActivity.class
android/support/multidex/MultiDexApplication.class
android/support/multidex/MultiDex.class
android/support/multidex/MultiDex$V19.class
android/support/multidex/MultiDex$V4.class
Run Code Online (Sandbox Code Playgroud)

这导致我的主dex文件中列出的类是可以的.我使用一个使用以下代码的库来列出dexfile中的所有类,但只获取主"clesses.dex"的条目,而不是所有其他加载的dex文件的条目,因为新的DexFile只检查"classes.dex" :

private static List<String> getPaths(final String[] sourcePaths) {
    List<String> result = new ArrayList<String>();

    for (String s : sourcePaths) {
      try {
        DexFile dexfile = new DexFile(s);
        Enumeration<String> entries = dexfile.entries();

        while (entries.hasMoreElements()) {
          result.add(entries.nextElement());
        }
      } catch (IOException ioe) {
        Log.w(TAG, "cannot open file=" + s + ";Exception=" + ioe.getMessage());
      }
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

现在的单一路径通过以下方式确定:

application.getApplicationContext().getApplicationInfo().sourceDir;
Run Code Online (Sandbox Code Playgroud)

结果像/data/../myapplicationname.apk

还有另一种可能性来列出dex文件中的所有类吗?或者目前在ClassLoaders中的所有课程?该库对项目至关重要,并使用此方法稍后通过反射查找组件实现.

EDIT1: 如果发现classes2.dex文件位于:/data/data/com./code_cache/secondary-dexes/com.-1.apk.classes2.dex

但是当使用带有此路径的新DexFile()时,将抛出IOEsxception,并显示消息"无法打开dexfile".

android classloader dex dexclassloader android-multidex

2
推荐指数
1
解决办法
3597
查看次数