android 插件化 r.java_Android插件化初探之apk加载和反射调用函数

一、整体试验步骤

1.建立子apk,新建一个android应用项目,叫firstplugin

2.在java根目录下新建一个类,叫LoginImpl

3.在LoginImpl.java中实现一个静态方法, login(),此方法只输出一个Log

package com.zht.car.firstplugin;

import android.util.Log;

import android.widget.Toast;

public class LoginImpl {

public static void login(){

Log.i("LoginImpl", "login");

}

}

1

2

3

4

5

6

7

8

9

10

packagecom.zht.car.firstplugin;

importandroid.util.Log;

importandroid.widget.Toast;

publicclassLoginImpl{

publicstaticvoidlogin(){

Log.i("LoginImpl","login");

}

}

4.编译生成apk,push到手机的/sdcard目录,此处生成的文件名为firstplugin-debug.apk

5.开始建宿主apk,新建另外一个Android应用项目PlugInHostApp

6.在MainActivity的onCreate中增加如下代码:

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

String dexOutputDir = getApplicationInfo().dataDir;

String apkpath = "/sdcard/firstplugin-debug.apk";

DexClassLoader loader = new DexClassLoader(apkpath, dexOutputDir,

null,getClass().getClassLoader());

try {

Class<?> aClass = loader.loadClass("com.zht.car.firstplugin.LoginImpl");

Object aClassInstance = aClass.newInstance();

Method method = aClass.getMethod("login");

method.invoke(null, null);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

StringdexOutputDir=getApplicationInfo().dataDir;

Stringapkpath="/sdcard/firstplugin-debug.apk";

DexClassLoaderloader=newDexClassLoader(apkpath,dexOutputDir,

null,getClass().getClassLoader());

try{

Class<?>aClass=loader.loadClass("com.zht.car.firstplugin.LoginImpl");

ObjectaClassInstance=aClass.newInstance();

Methodmethod=aClass.getMethod("login");

method.invoke(null,null);

}catch(ClassNotFoundExceptione){

e.printStackTrace();

}catch(IllegalAccessExceptione){

e.printStackTrace();

}catch(InstantiationExceptione){

e.printStackTrace();

}catch(NoSuchMethodExceptione){

e.printStackTrace();

}catch(InvocationTargetExceptione){

e.printStackTrace();

}

}

7.编译运行,看log中是否输出了login这个字符串

二、遇到的问题和解决方法

1.java.lang.ClassNotFoundException: Didn’t find class “com.zht.car.firstplugin.LoginImpl” on path错误

解决方法:

查看是否有访问外部存储目录的权限(笔者遇到的就是这个问题,程序不会在new DexClassLoader时报无权限访问或者找不到文件的错误,而会在loadClass时报找不到类的错误)

关闭Android Studio的Instant run选项,在菜单Settings->Build, Execution, Deployment中(笔者是在Ubuntu中使用Android Studio,没找到此选项)

打赏

f69872ab5631b766bfb8c62b6b7d28fa.png微信扫一扫,打赏作者吧~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值