ClassLoader 加载外部 apk 内的普通类

新建工程 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();
            }
        });
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章