Android加载未安装的APK中的类

学习自

https://blog.csdn.net/fwt336/article/details/53336810

他的才是加载apk里的内容,想看加载外源apk的可以去这个链接里看。我这里图方便,直接加载dex里的东西了。


熟悉ClassLoader的朋友都知道,PathClassLoader仅仅能加载已安装的APK中的类,DexClassLoader就灵活度很高了,许多压缩文件他都可以进行一个加载。

所以我们可以在程序运行的时候,动态加载某个压缩文件中的class然后进行一个调用。我们今天要做的就是这样一件事。

现在我有这样一个dex,里面有一个类,我调用他的方法就可以得到一段文字,然后我把这段文字更新到UI上,这是我打算实现的。


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button bt = findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    bt.setText(get());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private String get() throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/classes2.dex";

        File oDexFile = new File(getDir("odex", Context.MODE_PRIVATE).getAbsolutePath());
        ClassLoader dexClassLoader = new DexClassLoader(path,// dexPath
                oDexFile.getAbsolutePath(),// optimizedDirectory
                null,
                getClassLoader());
        Class c = dexClassLoader.loadClass("com.example.myapplication.WantFix");
        Method method = c.getDeclaredMethod("get");
        String s= (String) method.invoke(null);
        Log.i("xbh", "get: " + s);
        return s;
    }
}

这里的代码成功搞定,也很简单,就不多赘述了。


但是如果本地已经有一样的类的了话,会率先加载本地的类,这就让人很蛋疼了。因为这个DexClassLoader不仅会搜索自己管辖的dex下的内容,更是会率先把任务交给BaseClassLoader来搜索。找不到再自己进行一个搜索。所以我们需要进行一个同名类的替换,不过这就是热修复的话题了。而且正常情况下不会有相同类。

猜你喜欢

转载自blog.csdn.net/qq_36523667/article/details/80330728