AndFix 使用详解

简介: AndFix 使用详解

AndFix基本介绍


已经好几年没有维护了,阿里出了一个收费的。这个已经被放弃了。这里只是简单的介绍一下用法。如果不想看的,可以直接跳过


AndFix是一个在线修复bug的解决方案,而不是重新发布Android App。它是作为Android库发布的。Andfix是“Android热修复”的缩写。


AndFix支持Android 2.3 - 7.0版本,支持ARM和X86架构,支持Dalvik和ART runtime,支持32位和64位


AndFix补丁的压缩文件格式是.apatch。它会从你自己的服务器发送到客户端来修复你的应用程序的bug。


AndFix 只用用于方法级别的替换,使用场景有限


AndFix 执行流程及核心原理


0a2653c851af460fa595bd959398a8f1.png


从图中看到 A 调用 B,B 调用 C,但是 B 出了 bug。出现bug 以后 通过 AndFix 生成一个 patch,这个patch 中包含了要被替换的 B,然后执行的顺序就成为了 A 调用 B’ ,B’ 调用 C,这样就避免了调用 bug。


修复 Bug 的步骤


使用 AndFix 完成线上bug 修复


1,集成


implementation 'com.alipay.euler:andfix:0.5.0@aar'


2,AndFix 使用非常简单,只有三个 api (github),下面对他做一个简单的封装:


public class AndFixManager {
    private static AndFixManager mInstance = null;
    private PatchManager mPatchManger = null;
    public static AndFixManager getInstance() {
        if (mInstance == null)
            synchronized (AndFixManager.class) {
                if (mInstance == null) {
                    mInstance = new AndFixManager();
                }
            }
        return mInstance;
    }
    /**
     * 初始化 AndFix 方法
     *
     * @param context
     */
    public void initPatch(Context context) {
        mPatchManger = new PatchManager(context);
        mPatchManger.init(getVersionName(context));
        mPatchManger.loadPatch();
    }
    /**
     * 加载 path 文件
     *
     * @param path
     */
    public void addPath(String path) {
        if (mPatchManger != null) {
            try {
                mPatchManger.addPatch(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static String getVersionName(Context context) {
        String version = "1.0.0";
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
            version = packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return version;
    }
}


注意在 Application 中进行初始化:


 AndFixManager.getInstance().initPatch(this);


3,准备一个有 bug 的 apk 并安装到手机


public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    /**
     * 文件后缀名
     */
    private static final String FILE_END = ".apatch";
    /**
     * 文件路径
     */
    private String mPatchDir;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_one).setOnClickListener(this);
        findViewById(R.id.btn_two).setOnClickListener(this);
        mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";
        //创建文件夹
        File file = new File(mPatchDir);
        if (file.exists()) {
            file.mkdir();
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_one:
                printLog();
                break;
            case R.id.btn_two:
                AndFixManager.getInstance().addPath(getPatchName());
                break;
        }
    }
    /**
     * bug 方法
     */
    public void printLog() {
        String error = null;
        Log.e("-----", "printLog: " + Integer.valueOf(error));
    }
    /**
     * 构造文件名
     *
     * @return
     */
    private String getPatchName() {
        return mPatchDir.concat("345").concat(FILE_END);
    }
}


我们创建了两个按钮,按钮 one 执行bug 方法,two 进行修复,注意修复传入的路径。接着打包,主要要 replace 有签名的包,打完包后给它改一个名字 为 old.apk。然后保存在一个文件夹中。


4,分析解决 bug 后,build 一个新的Apk


我们现在找到 bug 了,然后进行修复:


/**
     * bug 方法
     */
    public void printLog() {
//        String error = null;
//        Log.e("-----", "printLog: " + Integer.valueOf(error));
        Toast.makeText(this, "没有bug", Toast.LENGTH_LONG).show();
    }


我们修复了 bug,明企鹅弹出了一个提示框,接着进行 replace 打包,保存名字为 new.apk。将他 和 old .apk 放在一起


5,构建 patch 文件


下载构建工具


其中 apkpatch.bat 是 window 用到的,apkpatch.sh 是苹果用到的,


我创建了一个 output 文件夹用来保存 patch 文件,然后将 old.apk 和 new.apk ,KeyStory.jsk 都放进去了,因为我们要用 apkpath 来比较 old 和 new 的变化。接着我们来看一下怎么生成 patch 文件。


打开 cmd ,进入上面的目录,输入 apkpatch.bat 就可以查看对应命令和解释


apkpatch -f <new> -t <old> -o <output> -k <keystore> -p <***> -a <alias>


生成 patch 文件所用到的命令


apkpatch -m <apatch_path…> -k -p <***> -a -e <***>


合并多个 patch 文件为 1 个的时候用到的命令


-f :没有 bug 的 apk

-t :有 bug 的 apk

-o:patch 文件输出路径

-k:keyStore

-p:密码

-a:别名

-e:密码

下面我们来看下一生成 patch文件:


可以看到他将两者的差异找到了,就是 printLog 方法。接着我们看一下输出的 patch 文件:

0a2653c851af460fa595bd959398a8f1.png


这就是生成的文件,其中我们只需要用到 .apatch 文件,345是我自己改的哈。。


patch 安装


将我们生成的 patch copy 到程序中定义的路径中,就是我们在程序中创建的那个路径。可以进行 copy,也可以进行 adb push ,都可以。只要将 patch 文件弄进去就好了。这里我通过 adb 的方式:

0a2653c851af460fa595bd959398a8f1.png

可以看到已经成功了。


然后打开 app ,点击修复按钮之后重启应用,就会发现bug已经修复了。



相关文章
|
测试技术 UED Python
App自动化测试:高级控件交互技巧
Appium 的 Actions 类支持在移动应用自动化测试中模拟用户手势,如滑动、长按等,增强交互性测试。ActionChains 是 Selenium 的概念,用于网页交互,而 Actions 专注于移动端。在Python中,通过ActionChains和W3C Actions可以定义手势路径,例如在手势解锁场景中,先点击设置,然后定义触点移动路径执行滑动解锁,最后验证解锁后的元素状态。此功能对于确保应用在复杂交互下的稳定性至关重要。
|
网络协议 物联网 iOS开发
iOS - App 与外设间的通信方式
1、前言 一般 iOS 开发者做 App 开发大部分时候都是通过 Http(s) 请求跟后台服务器打交道,做一些信息展示和用户交互。很少涉及到去跟外部硬件设备连接的开发。随着近年来车联网和物联网的兴起,智能家居和智能硬件的逐步火热,越来越多的 App 被开发出来,用来跟硬件设备进行来连接,获取硬件相关信息展示或者发送指令控制硬件来提供服务。
2484 0
|
XML 前端开发 Android开发
Android NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端
Android NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端 网上有一个StickyScrollView,称之为粘性ScrollView,比如一个垂直方向的布局,依次摆放几个子View,当某一个子View滚到到顶端时候要停靠在顶部,悬停在顶部的位置不动。
2998 0
|
流计算 计算机视觉 索引
使用ffmpeg将视频转成HLS(m3u8)格式
HLS (HTTP Live Streaming)是苹果推出的视频流协议,HLS格式的视频包含一个m3u8文本文件,以及众多的.ts的视频片段,而m3u8文本文件的作用就是将这些ts片段索引起来。 因为HLS协议是将视频切分成很多小的ts片段,这些小片段很适合放到cdn上,有很多视频文章都使用了hls格式传输视频。今天我在这里教大家如何用ffmpeg将mp4格式的视频转为HLS(m3u8)格式。
1079 0
|
7月前
|
自然语言处理 安全 搜索推荐
阿里通义等提出Chronos:慢思考RAG技术助力新闻时间线总结
在数字化时代,新闻信息的指数级增长使得从海量文本中提取和整理历史事件的时间线变得至关重要。为了应对这一挑战,阿里巴巴通义实验室与上海交通大学的中断者提出了一种基于Agent的新闻时间线摘要新框架——CH RONOS,源自希腊神话中的时间之神柯罗诺斯,该框架通过迭代多轮的自我提问方式,结合检索增强生成技术,从互联网上检索相关事件信息,并生成时间顺序的新闻摘要,为新闻时间线摘要生成提供了一种全新的解决方案。
361 44
|
7月前
|
人工智能 算法 API
谷歌AI Gemini 2.5 pro国内使用教程, 2025最新版!
在 2025 年 2 月初,谷歌又推出了 Gemini 2.0 Pro 系列模型,进一步巩固了其在 AI 领域的领先地位,同时也正式向外界宣告,我们进入了 Gemini 2.0 时代
3452 5
|
存储 缓存 算法
大文件 MD5 SHA 校验时间优化之路
【8月更文挑战第12天】处理大文件的MD5与SHA校验时,可通过选择高效算法实现、分块读取处理文件、利用多线程并行处理、采用硬件加速及缓存校验结果等方式优化校验时间。例如,使用性能良好的加密库如`pycryptodome`替代Python的标准`hashlib`库;分块读取文件并逐块计算哈希值,减少内存占用;利用多线程处理不同文件块;若条件允许,使用硬件加速如Intel AES-NI指令集;以及缓存重复校验的文件哈希值避免重算。这些策略可显著提高校验速度和系统效率。
870 1
|
SQL Java 数据库连接
复杂 SQL 实现分组分情况分页查询
在处理数据库查询时,分页是一个常见的需求。尤其是在处理大量数据时,一次性返回所有结果可能会导致性能问题。因此,我们需要使用分页查询来限制返回的结果数量。同时,根据特定的条件筛选数据也是非常常见的需求。在本博客中,我们将探讨如何根据 camp_status 字段分为 6 种情况进行分页查询,并根据 camp_type 字段区分活动类型,返回不同的字段。我们将使用 SQL 变量来实现这一功能,并通过示例进行详细解释。
229 2
IntelliJ IDEA如何快速修改移动后的包名
IntelliJ IDEA如何快速修改移动后的包名
941 0
IntelliJ IDEA如何快速修改移动后的包名
|
机器学习/深度学习 存储 大数据
大数据时代的处理挑战与突破
随着数字化时代的到来,大数据已经成为了企业和组织获取商业价值的关键资源。然而,大规模数据处理也带来了很多挑战,如数据量巨大、数据质量不一、处理效率低下等。本文将探讨大规模数据处理所面临的挑战,并介绍几种处理大规模数据的方法和技术,包括分布式系统、基于内存的计算、图形数据库、NoSQL数据库和机器学习算法等。同时,本文还将重点介绍近年来在大规模数据处理领域中的突破,如深度学习、人工智能等技术的应用。
452 1