读书人

Android应用开发拔高系列(4)And

发布时间: 2013-12-26 00:35:35 作者: rapoo

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方面的文章,终于又可以回来,继续挤时间来写博客,与大家一同探讨与分享。?

读书人网 >Android

热点推荐