您的位置:首页 > 移动开发 > Android开发

关于Android 动态加载 jar 文件

2015-03-19 17:05 197 查看
1.1  首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar      原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex。
      所以这条路不通,请大家注意。 1.2  当前哪些API可用于动态加载   1.2.1  DexClassLoader      这个可以加载jar/apk/dex,也可以从SD卡中加载,也是本文的重点。   1.2.2  PathClassLoader        只能加载已经安装到Android系统中的apk文件。1.3  代码

package com.example.dynamicloaddemo.jar;

public class DynamicTest implements IDynamic {

@Override
public String helloWorld() {
return "Hello World Form JAR";
}

}
将这个类导出,注意,编译的时候必须是 java 1.6 编译(java 1.7 编译会出现错误:Zip is good, but no classes.dex inside, and no valid .odex file in the same directory)

1.4  编译文件之后将上面的类打包为 dynamic.jar

1.4.1  下载jar 转化 dex 工具,将打包好的jar拷贝到SDK安装目录android-sdk-windows\platform-tools下,DOS进入这个目录,执行命名: dx --dex --output=test.jar dynamic.jar 1.4.2  将test.jar拷贝到 /data/data/packagename/app-libs/ 放在 SDCard 上会出现错误 Optimized data directory /data/data/com.example.dynamicloaddemo/files/test.jar is not owned by the current user. Shared storage cannot protect your application from code injection attacks.


程序代码:

public class MainActivity extends Activity {
Button mToastButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mToastButton = (Button) findViewById(R.id.main_btn);

// Before the secondary dex file can be processed by the DexClassLoader,
// it has to be first copied from asset resource to a storage location.
// final File dexInternalStoragePath = new File(getDir("dex",
// Context.MODE_PRIVATE),SECONDARY_DEX_NAME);
// if (!dexInternalStoragePath.exists()) {
// mProgressDialog = ProgressDialog.show(this,
// getResources().getString(R.string.diag_title),
// getResources().getString(R.string.diag_message), true, false);
// // Perform the file copying in an AsyncTask.
// // 从网络下载需要的dex文件
// (new PrepareDexTask()).execute(dexInternalStoragePath);
// } else {
// mToastButton.setEnabled(true);
// }

System.out.println(getDir("libs", Context.MODE_PRIVATE));
System.out.println(getFilesDir());
System.out.println(getCacheDir());
System.out.println(getDir("libs", Context.MODE_PRIVATE));
System.out.println(getDir("libs", Context.MODE_PRIVATE));

mToastButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Internal storage where the DexClassLoader writes the
// optimized dex file to.
// final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
final File optimizedDexOutputPath = new File(getDir("libs", Context.MODE_PRIVATE) + File.separator + "test.jar");
// Initialize the class loader with the secondary dex file.
// DexClassLoader cl = new
// DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
// optimizedDexOutputPath.getAbsolutePath(),
// null,
// getClassLoader());
/*
DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(), Environment
.getExternalStorageDirectory().toString(), null, getClassLoader());
*/
DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(), getDir("libs", Context.MODE_PRIVATE).getAbsolutePath(), null, getClassLoader());
Class<?> libProviderClazz = null;

try {
// Load the library class from the class loader.
// 载入从网络上下载的类
// libProviderClazz =
// cl.loadClass("com.example.dex.lib.LibraryProvider");
libProviderClazz = cl.loadClass("com.example.dynamicloaddemo.jar.DynamicTest");

// Cast the return object to the library interface so that
// the
// caller can directly invoke methods in the interface.
// Alternatively, the caller can invoke methods through
// reflection,
// which is more verbose and slow.
// LibraryInterface lib = (LibraryInterface)
// libProviderClazz.newInstance();
IDynamic lib = (IDynamic) libProviderClazz.newInstance();

// Display the toast!
// lib.showAwesomeToast(view.getContext(), "hello 世界!");
Toast.makeText(MainActivity.this, lib.helloWorld(), Toast.LENGTH_SHORT).show();
} catch (Exception exception) {
// Handle exception gracefully here.
exception.printStackTrace();
}
}
});

}

}

1.5  运行,出现 Hello World From JAR , 表明动态加载成功。

本文出自 “Lua学习笔记” 博客,请务必保留此出处http://mythwind.blog.51cto.com/6506705/1622297
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: