有没有办法让在给定classes.dex文件中的类名? [英] Is there a way to get the class names in a given classes.dex file?

查看:221
本文介绍了有没有办法让在给定classes.dex文件中的类名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个家庭自动化应用。我想添加一个插件系统。我有一个测试导出的测试类(子类按钮)为APK文件并把它放在我的应用程序的文件目录。我能够创建这个类的一个新实例,并使用把它放在我查看 DexClassLoader .loadClass

下一步是为扫描所有APK的这个目录中,并在其中获得的类的名称。

我发现DexFile类,做到了这一点但它抛出以下例外情况:

  04-18 17:26:15.697:E / dalvikvm(726):无法打开DEX缓存/data/dalvik-cache/data@data@com.strutton。 android.testplugin @文件@ testloadclass.apk @ classes.dex':没有这样的文件或目录04-18 17:26:15.705:I / dalvikvm(726):无法打开或创建/data/data/com.strutton.android.testplugin/files/testloadclass.apk缓存(/数据/达尔维克缓存/数据@ @数据@ com.strutton.android.testplugin文件@ testloadclass.apk @ classes.dex)

这似乎是试图找到在系统缓存优化DexFile,但我没有权限到缓存目录。从我所看到的这可能是由于设计,我没有与一个问题。有另一种方式来解析一个DEX文件,并从它那里得到的类名称?

我已经看过源为一些DEX反编译器项目。我必须推出自己的解决方案?

下面是我的测试应用程序code(从我的活动OnCreate中),以防万一我错过了什么:

  {尝试
        ArrayList的<串GT; UIPlugins =新的ArrayList<串GT;();
        最终文件FILESDIR = this.getFilesDir();
        最后文件TMPDIR = GETDIR(DEX,0);
        最后DexClassLoader类加载器=新DexClassLoader(filesDir.getAbsolutePath()+/ testloadclass.apk
                tmpDir.getAbsolutePath(),
                空,this.getClass()getClassLoader());
        最后一类<按钮和GT; classToLoad =
                (类<按钮和GT;)classloader.loadClass(com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn);
        巴顿则myButton = classToLoad.getDeclaredConstructor(Context.class).newInstance(本);
        mybutton.setId(2);
        mybutton.setOnClickListener(本);
        main.addView(myButton的);
        //到这里一切正常
        //此行抛出的异常
        DexFile mDexFile =新DexFile(filesDir.getAbsolutePath()+/ testloadclass.apk);
        枚举<串GT;类名= mDexFile.entries();
        而(classNames.hasMoreElements()){
            字符串的className = classNames.nextElement();
            如果(className.endsWith(IRDroidUIPlugIn)){
                UIPlugins.add(的className);
            }
        }
        最后一类<按钮和GT; classToLoad =
                (类<按钮和GT;)classloader.loadClass(com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn);
        巴顿则myButton = classToLoad.getDeclaredConstructor(Context.class).newInstance(本);
        mybutton.setId(2);
        mybutton.setOnClickListener(本);
        main.addView(myButton的);
        btn.setText(tmpDir.getAbsolutePath());
      }赶上(例外五){
        e.printStackTrace();
    }


解决方案

而不是:

  DexFile mDexFile =新DexFile(filesDir.getAbsolutePath()+/ testloadclass.apk);

尝试:

  DexFile mDexFile = DexFile.loadDex(filesDir.getAbsolutePath()+/ testloadclass.apk,tmpDir.getAbsolutePath()+/ testloadclass.odex,0);

I am building a home automation app. I am trying to add a plugin system. I have as a test exported a test class (that subclasses Button) as an APK file and put it in my app's file directory. I was able to create a new instance of this class and put it in my View using DexClassLoader and .loadClass.

The next step is to scan all the APK's in this directory and get the names of the classes in them.

I found the DexFile class that does just that however it throws the following exceptions:

04-18 17:26:15.697: E/dalvikvm(726): Can't open dex cache '/data/dalvik-cache/data@data@com.strutton.android.testplugin@files@testloadclass.apk@classes.dex': No such file or directory

04-18 17:26:15.705: I/dalvikvm(726): Unable to open or create cache for /data/data/com.strutton.android.testplugin/files/testloadclass.apk (/data/dalvik-cache/data@data@com.strutton.android.testplugin@files@testloadclass.apk@classes.dex)

It would seem that it is trying to find the optimized DexFile in the system cache but I do not have permissions to the cache directory. From what I can see this is probably by design and I don't have a problem with that. Is there another way to parse a DEX file and get the class names from it?

I have looked at the source for some of the dex decompiler projects. Do I have to roll my own solution?

Here is my test app code (from my Activity OnCreate) just in case I missed something:

    try {
        ArrayList<String> UIPlugins = new ArrayList<String>();
        final File filesDir = this.getFilesDir();
        final File tmpDir = getDir("dex", 0);
        final DexClassLoader classloader = new DexClassLoader( filesDir.getAbsolutePath()+"/testloadclass.apk",
                tmpDir.getAbsolutePath(),
                null, this.getClass().getClassLoader());
        final Class<Button> classToLoad = 
                (Class<Button>) classloader.loadClass("com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn");
        Button mybutton = classToLoad.getDeclaredConstructor(Context.class).newInstance(this);
        mybutton.setId(2);
        mybutton.setOnClickListener(this);
        main.addView(mybutton);
        // Up to here everything works as expected
        // This line throws the exceptions
        DexFile mDexFile = new DexFile(filesDir.getAbsolutePath()+"/testloadclass.apk";);
        Enumeration<String> classNames = mDexFile.entries();
        while (classNames.hasMoreElements()){
            String className = classNames.nextElement();
            if (className.endsWith("IRDroidUIPlugIn")){
                UIPlugins.add(className);
            }
        }
        final Class<Button> classToLoad = 
                (Class<Button>) classloader.loadClass("com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn");
        Button mybutton = classToLoad.getDeclaredConstructor(Context.class).newInstance(this);
        mybutton.setId(2);
        mybutton.setOnClickListener(this);
        main.addView(mybutton);
        btn.setText(tmpDir.getAbsolutePath());
      } catch (Exception e) {
        e.printStackTrace();
    }

解决方案

Instead of:

DexFile mDexFile = new DexFile(filesDir.getAbsolutePath()+"/testloadclass.apk";);

try:

DexFile mDexFile = DexFile.loadDex(filesDir.getAbsolutePath()+"/testloadclass.apk", tmpDir.getAbsolutePath()+"/testloadclass.odex", 0);

这篇关于有没有办法让在给定classes.dex文件中的类名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆