android 动态加载sd卡的jar文件

 

android 动态加载sd卡的jar文件


下面以一个例子列出Android程序运行时动态加载sd卡jar包的步骤:


1. 首先要准备好jar包。

本例中要对com.test.dynamic包进行打包,com.test.dynamic包下面有一个MyClass类.代码如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.test.dynamic;  
  2.   
  3. import android.util.Log;  
  4.   
  5. public class MyClass {  
  6.     public MyClass() {  
  7.         Log.d("com.test.dynamic""MyClass:constructor called");  
  8.     }  
  9.   
  10.     public void doSomething() {  
  11.         Log.d("com.test.dynamic""MyClass:doSomething called");  
  12.     }  
  13. }  

eclipse中选择com.test.dynamic包,使用export导出得到test.jar. 接下来一定不能忘记使用dx命令对test.jar处理,否则的话会报Java.lang.ClassNotFoundException异常.dx命令位于sdk\build-tools\android-4.4W下面(android-4.4W是android的一个版本,其他android版本下面也能找到dx.bat). cmd命令行模式下进入dx.bat所在目录,使用dx --dex --output=dynamic.jar test.jar ,dynamic.jar是对test.jar处理后得到的jar文件.


重要:

dx.bat命令使用示例如下:dx.bat --dex --output=输出.jar 输入.jar。



2. 把dynamic.jar 拷贝到手机的sd卡目录下,删除掉eclipse项目中的com.test.dynamic包

不同的手机sd卡目录不太一样,比如本人使用的魅族3手机sd卡目录是\storage\emulated\0.如果不知道手机sd卡目录的话,大家可以打印Environment.getExternalStorageDirectory()信息来查看sd卡目录.


3.android程序运行时动态加载sd卡中的jar包

下面简单写了一个Activity来动态加载jar,代码如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.dynamicLoading;  
  2.   
  3. import java.io.File;  
  4. import java.lang.reflect.Method;  
  5. import dalvik.system.DexClassLoader;  
  6. import android.annotation.SuppressLint;  
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.os.Environment;  
  10.   
  11. public class Main extends Activity {  
  12.     @SuppressLint("NewApi")  
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.           
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.           
  19.         String libPath = Environment.getExternalStorageDirectory()+ File.separator + "dynamic.jar"// 要动态加载的jar   
  20.         File dexDir = getDir("dex", MODE_PRIVATE); // 优化后dex的路径  
  21.           
  22.         /** 
  23.          * 进行动态加载,利用java的反射调用com.test.dynamic.MyClass的方法 
  24.          */  
  25.         DexClassLoader classLoader = new DexClassLoader(libPath, dexDir.getAbsolutePath(), null, getClassLoader());  
  26.         try {  
  27.             Class<Object> cls = (Class<Object>) classLoader.loadClass("com.test.dynamic.MyClass");  
  28.             Object object = cls.newInstance();  
  29.             Method method = cls.getMethod("doSomething"null);  
  30.             method.invoke(object, null);  
  31.         } catch (Exception e) {  
  32.             e.printStackTrace();  
  33.         }  
  34.   
  35.     }  
  36. }  


程序运行后logcat打印出如下的信息,说明动态加载jar包成功:


下面对代码进行分析,

DexClassLoader的构造函数DexClassLoader(String dexPath,String optimizedDirectory,String libraryPath, ClassLoader parent)需要传入四个参数.第一个参数dexPath是dex文件的路径,在本例当中是dynamic.jar的路 径. optimizedDirectory是优化后的dex文件的路径,optimizedDirectory一定不能为null,官方文档上不建议把优化后的dex文件存放在外存,本例当中优化后的app_dex存放在/data/data/packagename/目录下(app_是android系统自动加的前缀). libraryPath是包含原生库的路径,可为null,本例中传的就是null。parent参数是父加载器.本例的大致流程:系统对sd卡下的dynamic.jar包进行动态加载,loadClass方法返回一个Class对象,利用java的反射机制调用MyClass当中的方法doSomething()

大家有什么问题或者意见可以和我交流~

下面以一个例子列出Android程序运行时动态加载sd卡jar包的步骤:


1. 首先要准备好jar包。

本例中要对com.test.dynamic包进行打包,com.test.dynamic包下面有一个MyClass类.代码如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.test.dynamic;  
  2.   
  3. import android.util.Log;  
  4.   
  5. public class MyClass {  
  6.     public MyClass() {  
  7.         Log.d("com.test.dynamic""MyClass:constructor called");  
  8.     }  
  9.   
  10.     public void doSomething() {  
  11.         Log.d("com.test.dynamic""MyClass:doSomething called");  
  12.     }  
  13. }  

eclipse中选择com.test.dynamic包,使用export导出得到test.jar. 接下来一定不能忘记使用dx命令对test.jar处理,否则的话会报Java.lang.ClassNotFoundException异常.dx命令位于sdk\build-tools\android-4.4W下面(android-4.4W是android的一个版本,其他android版本下面也能找到dx.bat). cmd命令行模式下进入dx.bat所在目录,使用dx --dex --output=dynamic.jar test.jar ,dynamic.jar是对test.jar处理后得到的jar文件.


重要:

dx.bat命令使用示例如下:dx.bat --dex --output=输出.jar 输入.jar。



2. 把dynamic.jar 拷贝到手机的sd卡目录下,删除掉eclipse项目中的com.test.dynamic包

不同的手机sd卡目录不太一样,比如本人使用的魅族3手机sd卡目录是\storage\emulated\0.如果不知道手机sd卡目录的话,大家可以打印Environment.getExternalStorageDirectory()信息来查看sd卡目录.


3.android程序运行时动态加载sd卡中的jar包

下面简单写了一个Activity来动态加载jar,代码如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.dynamicLoading;  
  2.   
  3. import java.io.File;  
  4. import java.lang.reflect.Method;  
  5. import dalvik.system.DexClassLoader;  
  6. import android.annotation.SuppressLint;  
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.os.Environment;  
  10.   
  11. public class Main extends Activity {  
  12.     @SuppressLint("NewApi")  
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.           
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.           
  19.         String libPath = Environment.getExternalStorageDirectory()+ File.separator + "dynamic.jar"// 要动态加载的jar   
  20.         File dexDir = getDir("dex", MODE_PRIVATE); // 优化后dex的路径  
  21.           
  22.         /** 
  23.          * 进行动态加载,利用java的反射调用com.test.dynamic.MyClass的方法 
  24.          */  
  25.         DexClassLoader classLoader = new DexClassLoader(libPath, dexDir.getAbsolutePath(), null, getClassLoader());  
  26.         try {  
  27.             Class<Object> cls = (Class<Object>) classLoader.loadClass("com.test.dynamic.MyClass");  
  28.             Object object = cls.newInstance();  
  29.             Method method = cls.getMethod("doSomething"null);  
  30.             method.invoke(object, null);  
  31.         } catch (Exception e) {  
  32.             e.printStackTrace();  
  33.         }  
  34.   
  35.     }  
  36. }  


程序运行后logcat打印出如下的信息,说明动态加载jar包成功:


下面对代码进行分析,

DexClassLoader的构造函数DexClassLoader(String dexPath,String optimizedDirectory,String libraryPath, ClassLoader parent)需要传入四个参数.第一个参数dexPath是dex文件的路径,在本例当中是dynamic.jar的路 径. optimizedDirectory是优化后的dex文件的路径,optimizedDirectory一定不能为null,官方文档上不建议把优化后的dex文件存放在外存,本例当中优化后的app_dex存放在/data/data/packagename/目录下(app_是android系统自动加的前缀). libraryPath是包含原生库的路径,可为null,本例中传的就是null。parent参数是父加载器.本例的大致流程:系统对sd卡下的dynamic.jar包进行动态加载,loadClass方法返回一个Class对象,利用java的反射机制调用MyClass当中的方法doSomething()

大家有什么问题或者意见可以和我交流~

猜你喜欢

转载自blog.csdn.net/yangyikun0428/article/details/53765299