Android热修复与插件化(四)AndFix

一、热修复技术种类

这里写图片描述

技术对比

这里写图片描述

二、AndFix的基本介绍

官网

集成阶段:

1、在gradle中添加依赖
2、在代码中完成初始化

builde.gradle

这里写图片描述

MyApplication

这里写图片描述

AndFixPatchManager

这里写图片描述

准备阶段:

1、首先我们先builde一个有bug的old.apk安装到手机
2、分析bug并解决bug,builde一个new的apk

(需要签名打包的apk不要debug,自行解决)
有bug的代码:

public class MainActivity extends AppCompatActivity {

    private static final String FILE_END = ".apatch";
    private String patchDir;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建文件路径
        patchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
        //创建文件夹
        File file = new File(patchDir);
        //判断文件夹是否存在
        if (file == null || !file.exists()) {
            //不存在就创建
            file.mkdir();
        }
    }

    public void createBug(View view) {
        //打印log信息为null,应用闪退
        Utils.printLog();
    }

    public void fixBug(View view) {
        AndFixPatchManager.getInstance().addPatch(getPathName());
    }

    //构建Patch文件名
    private String getPathName() {
        return patchDir.concat("smile").concat(FILE_END);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.smile.mydemotwo.activity.MainActivity">

    <Button
        android:layout_width="88dp"
        android:layout_height="50dp"
        android:text="产生bug"
        android:onClick="createBug"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="8dp"
        android:layout_margin="10dp"/>

    <Button
        android:layout_width="88dp"
        android:layout_height="50dp"
        android:text="修复bug"
        android:onClick="fixBug"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="8dp"
        android:layout_margin="10dp"/>

</LinearLayout>

Patch生成阶段:

1、apkpatch命令及参数详解

1、先下载apkpatch工具工具
解压
这里写图片描述

这里写图片描述

这里写图片描述

-f:new.apk的文件路径
-t:是有bug的apk文件的路径
-o:是输出补丁包文件的目录
-k:是签名文件的路径
-p:是签名文件的密码
-a :是签名文件的别名
-e:是签名文件别名的密码

2、使用apkpatch命令生成apkpatch包

这里写图片描述
这里写图片描述

Patch安装阶段:

将补丁文件通过adb push放入到指定目录(开发中都是下载到指定目录)
点击修复bug按钮,加载补丁文件
再次启动应用,点击创建bug按钮,此时应用不会闪退,并弹出Toast

这里写图片描述

到这基本就完成了更新

总结阶段:

1、实际中不可能用adb push导入补丁,应该是下载
2、能否将AndFix模块组件化,为以后复用

将AndFix组件化

AndFixPatchManager :

public class AndFixPatchManager {

    private static AndFixPatchManager mInstance = null;

    private static PatchManager mPatchManager = null;

    private AndFixPatchManager() {
    }

    public static AndFixPatchManager getInstance() {
        if (mInstance == null) {

            synchronized (AndFixPatchManager.class) {

                if (mInstance == null) {

                    mInstance = new AndFixPatchManager();

                }
            }
        }
        return mInstance;
    }

    //初始化AndFix方法
    public void initPatch(Context context) {
        mPatchManager = new PatchManager(context);
        mPatchManager.init(Utils.getVersionName(context));
        mPatchManager.loadPatch();
    }

    //加载我们的patch文件,参数patch文件的路径
    public void addPatch(String path) {
        try {
            if (mPatchManager != null) {
                mPatchManager.addPatch(path);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

AndFixService

public class AndFixService extends Service {

    private static final int UPDATE_PATCH = 0x02;
    private static final int DOWNLOAD_PATCH = 0x01;
    private static final String FILE_END = ".apatch";
    //存放Patch文件的目录
    private String mPatchFileDir;
    //存放Patch文件
    private String mPatchFile;
    //消息转发
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_PATCH:
                    checkPatchUpdate();
                    break;
                case DOWNLOAD_PATCH:
                    downloadPatch();
                    break;
            }
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化
        init();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mHandler.sendEmptyMessage(UPDATE_PATCH);
        //这个返回值如果被系统回收之后不会被系统重启
        return START_NOT_STICKY;
    }

    //完成文件目录的构造
    private void init() {
        mPatchFileDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
        File file = new File(mPatchFileDir);
        try {
            if (file == null || !file.exists()) {
                file.mkdir();
            }
        } catch (Exception e) {
            e.printStackTrace();
            stopSelf();
        }
    }

    //检查是否有新的patch文件
    private void checkPatchUpdate() {
        //网络请求,失败停止服务
    }

    private void downloadPatch() {
        //网络请求,失败停止服务
        mPatchFile = mPatchFileDir.concat(System.currentTimeMillis() + "").concat(FILE_END);
    }
}

Demo地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值