本文主要是介绍Android中的类装载器DexClassLoader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- 类文件必须在本地,当程序运行时需要次类时,这时类装载器会自动装载该类,程序员不需要关注此过程。
- 编译的时候必须有这个类文件,否则编译不通过。
A class loader that loads classes from .jar
and .apk
files containing a classes.dex
entry. This can be used to execute code not installed as part of an application.
This class loader requires an application-private, writable directory to cache optimized classes. Use Context.getDir(String, int)
to create such a directory:
<code style="line-height: 14px;"><span class="typ" style="color: rgb(102, 0, 102);">File</span><span class="pln" style="color: rgb(0, 0, 0);"> dexOutputDir </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">getDir</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(136, 0, 0);">"dex"</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">);</span></code>
Do not cache optimized classes on external storage. External storage does not provide access controls necessary to protect your application from code injection attacks.
不要把优化优化后的classes文件存放到外部存储设备上,防代码注入攻击。
public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
Creates a DexClassLoader
that finds interpreted and native code. Interpreted classes are found in a set of DEX files contained in Jar or APK files.
创建一个DexClassLoader用来找出指定的类和本地代码(c/c++代码)。用来解释执行在DEX文件中的class文件。
路径的分隔符使用通过System的属性 path.separator
获得 :
.
String separeater = System.getProperty("path.separtor");
Parameters
dexPath | 需要装载的APK或者Jar文件的路径。包含多个路径用File.pathSeparator间隔开 ,在Android上默认是 ":" |
---|---|
optimizedDirectory | 优化后的dex文件存放目录,不能为null |
libraryPath | 目标类中使用的C/C++库的列表,每个目录用File.pathSeparator间隔开 ; 可以为 null |
parent | 该类装载器的父装载器,一般用当前执行类的装载器 |
- 通过PacageMangager获得指定的apk的安装的目录,dex的解压缩目录,c/c++库的目录
- 创建一个 DexClassLoader实例
- 加载指定的类返回一个Class
- 然后使用反射调用这个Class
- @SuppressLint("NewApi") private void useDexClassLoader(){
- //创建一个意图,用来找到指定的apk
- Intent intent = new Intent("com.suchangli.android.plugin", null);
- //获得包管理器
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resolveinfoes = pm.queryIntentActivities(intent, 0);
- //获得指定的activity的信息
- ActivityInfo actInfo = resolveinfoes.get(0).activityInfo;
- //获得包名
- String pacageName = actInfo.packageName;
- //获得apk的目录或者jar的目录
- String apkPath = actInfo.applicationInfo.sourceDir;
- //dex解压后的目录,注意,这个用宿主程序的目录,android中只允许程序读取写自己
- //目录下的文件
- String dexOutputDir = getApplicationInfo().dataDir;
- //native代码的目录
- String libPath = actInfo.applicationInfo.nativeLibraryDir;
- //创建类加载器,把dex加载到虚拟机中
- DexClassLoader calssLoader = new DexClassLoader(apkPath, dexOutputDir, libPath,
- this.getClass().getClassLoader());
- //利用反射调用插件包内的类的方法
- try {
- Class<?> clazz = calssLoader.loadClass(pacageName+".Plugin1");
- Object obj = clazz.newInstance();
- Class[] param = new Class[2];
- param[0] = Integer.TYPE;
- param[1] = Integer.TYPE;
- Method method = clazz.getMethod("function1", param);
- Integer ret = (Integer)method.invoke(obj, 1,12);
- Log.i("Host", "return result is " + ret);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- package com.suchangli.plugin1;
- public class Plugin1 {
- public int function1(int a, int b){
- return a+b;
- }
- }
这篇关于Android中的类装载器DexClassLoader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!