Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类? 二、准备 准备被调用Android
Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类
?
二、准备
准备被调用Android工程:TestB
ITest
public?class?TestBActivity?extends?Activity?implements?ITest?{
????/**?Called?when?the?activity?is?first?created.?*/
????@Override
????public?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.main);
????}
????@Override
????public?String?getMoney()?{
????????return?"1";
????}
}
代码说明:很简单的代码。将生成后的TestB.apk拷贝到SD卡的根目录下。
?
三、调用?
调用工程TestA
public?class?TestAActivity?extends?Activity?{
????/**?Called?when?the?activity?is?first?created.?*/
????@Override
????public?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.main);
????????String?path?=?Environment.getExternalStorageDirectory()?+?"/";
????????String?filename?=?"TestB.apk";
????????DexClassLoader?classLoader?=?new?DexClassLoader(path?+?filename,?path,
????????????????null,?getClassLoader());
????????try?{
????????????Class?mLoadClass?=?classLoader.loadClass("com.nmbb.TestBActivity");
????????????Constructor?constructor?=?mLoadClass.getConstructor(new?Class[]?{});
????????????Object?TestBActivity?=?constructor.newInstance(new?Object[]?{});
????????????
????????????Method?getMoney?=?mLoadClass.getMethod("getMoney",?null);
????????????getMoney.setAccessible(true);
????????????Object?money?=?getMoney.invoke(TestBActivity,?null);
????????????Toast.makeText(this,?money.toString(),?Toast.LENGTH_LONG).show();
????????????
????????}?catch?(ClassNotFoundException?e)?{
????????????e.printStackTrace();
????????}?catch?(SecurityException?e)?{
????????????e.printStackTrace();
????????}?catch?(NoSuchMethodException?e)?{
????????????e.printStackTrace();
????????}?catch?(IllegalArgumentException?e)?{
????????????e.printStackTrace();
????????}?catch?(InstantiationException?e)?{
????????????e.printStackTrace();
????????}?catch?(IllegalAccessException?e)?{
????????????e.printStackTrace();
????????}?catch?(InvocationTargetException?e)?{
????????????e.printStackTrace();
????????}
????}
}
执行的时候可以发现会自动生成TestB.dex文件。动态加载方面还可以搜索一下"Java动态加载"方面的资料,很有参考价值。可以发现比Android动态加载jar/dex使用起来方便得多。
?
四、下载
TestA.zip
TestB.zip
?
五、注意
6.1 别忘了加上SDCARD的写权限:
android.permission.WRITE_EXTERNAL_STORAGE
6.2 同样注意,不要再两个工程包含package和名称相同的接口,否则报错。(参见Android动态加载jar/dex的后期维护)
?
六、扩展阅读
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
(强烈推荐:QQ游戏动态调用Activity的方法:通过ClassLoader,loadClass Activity类,然后分别在主工程的onDestroy、onKeyDown、onPause、onRestart、onResume等生命周期方法中反射调用(Method、invoke)子工程的类方法来模拟实现整个生命周期。此外巧妙的通过解压缩APK文件来获取游戏的资源)
?
Android中文Wiki:DexFile
?
?
七、缺点
6.1 由于是使用反射,无法取得Context,也就是TestBActivity与普通的类毫无区别,没有生命周期。
?
八、推荐
Android版 程序员专用搜索
?
结束?
忙着换工作、忙着把翻译组转动Wiki平台、忙着推广翻译组...忙这忙那的,博客已经有近2个月没有写Android方面的文章,终于又可以回来,继续挤时间来写博客,与大家一同探讨与分享。?