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