新建工程 SimpleApk,新建 Person 类:
package com.gdeer.simpleapk;
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
打包,将生成的 simple.apk 放入另一个工程(这里是 GdTestHub)的 assets 目录下。
新建 CommonClassActivity,在 attachBaseContext 时,将 simple.apk 复制到应用的 data/data 目录下,并根据该路径生成 DexClassLoader。
在页面的按钮点击时,使用生成的 DexClassLoader 加载 Person 类,调用 set、get 方法:
public class CommonClassActivity extends AppCompatActivity {
private static String PLUGIN_APK_NAME = "simple.apk";
private DexClassLoader mClassLoader;
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
// 将 simple.apk 复制到 /data/data/packageName/files
File apkFile = newBase.getFileStreamPath(PLUGIN_APK_NAME);
FileUtil.copyFileFromAssets(newBase, PLUGIN_APK_NAME, apkFile, false);
// 获取 dex 文件(即 simple.apk)的路径
String dexPath = apkFile.getAbsolutePath();
// 构建 classLoader,optDir 设为 dexPath
mClassLoader = new DexClassLoader(dexPath, dexPath, null, getClassLoader());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common_class);
Button btnUse = findViewById(R.id.btn_use_common_class);
btnUse.setOnClickListener(v -> {
try {
// 点击后,加载 Person 类,调用 set、get 方法
Class<?> personClass = mClassLoader.loadClass("com.gdeer.simpleapk.Person");
Object person = personClass.newInstance();
Method setName = personClass.getMethod("setName", String.class);
Method getName = personClass.getMethod("getName");
setName.invoke(person, "gdeer");
String name = (String) getName.invoke(person);
Toast.makeText(CommonClassActivity.this, name, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}