新建工程 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();
}
});
}
}