美文网首页
Android利用DexClassLoader实现百变的方法

Android利用DexClassLoader实现百变的方法

作者: itfitness | 来源:发表于2021-10-30 11:40 被阅读0次

目录

实现效果

首先是加载第一种实现效果



然后是加载第二种实现效果



这两种效果都是通过动态加载想要执行的Class来实现的,其中要执行的Class中方法的逻辑可以随意替换,从而实现百变功能的方法,而这所有的实现都不需要重新安装APK

实现原理

这里的实现原理是借鉴了热修复的原理,其实就是利用DexClassLoader加载多种逻辑的Class从而实现百变方法,原理图大致如下所示:



先定义一个MethodProxy接口,然后定义MethodImpl实现MethodProxy接口,其中MethodImpl实现exec方法,exec方法可以实现多种逻辑,然后将每一种实现的逻辑所生成的class文件打包成dex文件,然后通过DexClassLoader加载这些逻辑不同但类名相同的Class,最终通过MethodProxy来对外统一执行exec方法

相关文章

Android10分钟手写热修复

实现步骤

1.定义MethodProxy接口
public interface MethodProxy {
    void exec(Context context);
}
2.实现MethodProxy接口
public class MethodImpl implements MethodProxy{
    @Override
    public void exec(Context context) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("我是消息");
        builder.setTitle("提示");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.create().show();
    }
}
3.获得MethodImpl的class文件

通过运行应用即可得到MethodImpl 的class文件,在如下位置


4.打包class文件

我们可以通过build-tools中的dx.bat将class文件打包成dex文件



在这之前我们先将dx.bat加入到Path环境变量中



由于我们只需要MethodImpl的class文件因此我们可以将其他的class文件排除

将无关的删除



然后我们回到debug目录

在该目录下打开命令行窗口执行如下命令
dx --dex --output=out.dex classes

该命令的意思是将classes下的文件打包为out.dex文件,执行完后生成out.dex文件


5.加载Class

首先我们先将out.dex放到SD卡中



我们在Activity中加载此dex中的Class,并执行exec方法

public class MainActivity extends AppCompatActivity {

    private DexClassLoader dexClassLoader;

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

    private void initClass() {
        try {
            File dexDir = new  File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),"/dex");
            File dexFile = new  File(dexDir,"out.dex");
            dexClassLoader = new DexClassLoader(dexFile.getAbsolutePath(),dexDir.getAbsolutePath(),null,getClassLoader());
        }catch (Exception e){
            Log.e("加载",e.getMessage());
        }
    }

    public void onClick(View view) {
        try {
            Class<?> methodImplClazz = dexClassLoader.loadClass("com.itfitness.dexclassloaderdemo.MethodImpl");
            MethodProxy methodProxy = (MethodProxy) methodImplClazz.newInstance();
            methodProxy.exec(this);
        }catch (Exception e){
            Log.e("加载",e.getMessage());
        }
    }
}

然后为了确保我们是执行的dex中的Class我们需要将项目中的MethodImpl文件删除




然后我们重新运行项目,效果如下


案例源码

https://gitee.com/itfitness/dex-class-loader-demo.git

相关文章

网友评论

      本文标题:Android利用DexClassLoader实现百变的方法

      本文链接:https://www.haomeiwen.com/subject/owrgaltx.html