Android中的动态类加载

时间:2015-12-26 06:08:08

标签: java android

我想为我的Android应用注入功能。 但是我一直在遭受'java.lang.ClassNotFoundException'。 我错过了什么样的事情?

  1. 简单类(只是.class文件)
  2. 布局和资源
  3. 活动
  4. 首先,我想做1。 但是有很多方法可以实现,我混淆了如何实现这一点。

    假设:

    1.File被下载到本地数据存储库。

    2.targetClassName是com.example.mari.myandroid.TestDinamicLoad。

    3.SDK& Build Tools版本,(没有proguard)     compileSdkVersion 22     buildToolsVersion“21.1.2”

    模式A:使用URLClassLoader

    编译:gradle编译,这只是原始类文件

    网址:https://drive.google.com/file/d/0B0Hrot21k8nYZ2pWNXBBMU5Qd2M/view?usp=sharing

        private void urlLoader(final File file){
            try {
                URL myurl[] = {new URL("file:" + file.toString())};
                URLClassLoader x = new URLClassLoader(myurl);
                Class c = x.loadClass(this.targetClassName);
                for (Field f : c.getDeclaredFields()) {
                    Log.v(TAG, f.getName() + " : " + f.toString());
                }
            }catch(Exception e){
                Log.v(TAG, e.toString());
            }
        }
    

    模式B:使用dexLoader

    编译:

        javac -classpath /Applications/adt-bundle-mac/sdk/platforms/android-22/android.jar TestDinamicLoad.java
        dx --dex --output TestDinamicLoad.jar TestDinamicLoad.java
    

    URL: https://drive.google.com/file/d/0B0Hrot21k8nYdG9wdHhiOWJIVE0/view?usp=sharing

        private void dexLoader(final File file){
        try {
            Context ctx     = getApplicationContext();
            String         dex_dir = ctx.getDir("dex", 0).getAbsolutePath();
            ClassLoader    parent  = getClass().getClassLoader();
            DexClassLoader loader  = new DexClassLoader(file.getPath(), dex_dir, null, parent);
            Class          c       = loader.loadClass(this.targetClassName);
            Object         o       = c.newInstance();
            Method m       = c.getMethod("func");
    
            m.invoke(o);
        } catch (Exception e) {
            Log.v(TAG, e.toString());
        }
    
    }
    

    错误:

        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani: urlLoader------
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani: java.lang.ClassNotFoundException: com.example.mari.myandroid.TestDinamicLoad
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.net.URLClassLoader.findClass(URLClassLoader.java:753)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity.urlLoader(MainActivity.java:109)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity.access$200(MainActivity.java:23)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity$1.postExecute(MainActivity.java:69)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.AsyncFileDownload.doInBackground(AsyncFileDownload.java:78)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.AsyncFileDownload.doInBackground(AsyncFileDownload.java:19)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at android.os.AsyncTask$2.call(AsyncTask.java:288)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.Thread.run(Thread.java:818)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:  Suppressed: java.lang.ClassNotFoundException: Didn't find class "com.example.mari.myandroid.TestDinamicLoad" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:          ... 12 more
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:      Suppressed: java.lang.ClassNotFoundException: com.example.mari.myandroid.TestDinamicLoad
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.Class.classForName(Native Method)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:              ... 13 more
        12-26 23:20:34.817 19078-19264/com.example.mari.myandorid2 V/murotani:  Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
    
    
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani: dexLoader------
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani: java.lang.ClassNotFoundException: Didn't find class "com.example.mari.myandroid.TestDinamicLoad" on path: DexPathList[[zip file "/data/data/com.example.mari.myandorid2/files/TestDinamicLoad.class"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity.dexLoader(MainActivity.java:91)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity.access$300(MainActivity.java:23)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity$1.postExecute(MainActivity.java:70)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.AsyncFileDownload.doInBackground(AsyncFileDownload.java:78)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.AsyncFileDownload.doInBackground(AsyncFileDownload.java:19)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at android.os.AsyncTask$2.call(AsyncTask.java:288)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.Thread.run(Thread.java:818)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:  Suppressed: java.io.IOException: Expected valid zip or dex file: '/data/data/com.example.mari.myandorid2/files/TestDinamicLoad.class'
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexFile.openDexFileNative(Native Method)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexFile.openDexFile(DexFile.java:295)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexFile.<init>(DexFile.java:111)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexFile.loadDex(DexFile.java:151)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexPathList.loadDexFile(DexPathList.java:265)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexPathList.makeDexElements(DexPathList.java:231)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexPathList.<init>(DexPathList.java:109)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:57)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at com.example.mari.myandorid2.MainActivity.dexLoader(MainActivity.java:90)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:          ... 10 more
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:  Suppressed: java.lang.ClassNotFoundException: Didn't find class "com.example.mari.myandroid.TestDinamicLoad" on path: DexPathList[[zip file "/data/app/com.example.mari.myandorid2-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:          ... 12 more
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:      Suppressed: java.lang.ClassNotFoundException: com.example.mari.myandroid.TestDinamicLoad
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.Class.classForName(Native Method)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:              ... 13 more
        12-26 23:20:34.837 19078-19264/com.example.mari.myandorid2 V/murotani:  Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
    

    Refered: ClassNotFoundException during Dynamic Class loading in android http://tech.co/android-security-2014-07 http://larshamren.blogspot.jp/2012/02/android-dynamically-loading-classes.html

1 个答案:

答案 0 :(得分:0)

我认为你想要的是动态加载apk:

  1. 动态加载类
  2. 动态加载Android资源
  3. 动态注册活动
  4. 这些现已在Small@github上提供,您可以尝试并享受乐趣。