阿里AndFix 热修复(转载)

本文转自http://blog.csdn.net/lpftobetheone/article/details/50435371

搜索发现有这3种方式可以实现(至于其他的方式,暂不清楚)

1.dexposed     github https://github.com/alibaba/dexposed

2.andfix   github https://github.com/alibaba/AndFix

3.bsdiff  http://blog.csdn.net/lazyer_dog/article/details/47173013

dexposed和andfix是alibaba的开源项目,都是apk增量更新的实现框架,目前dexposed的兼容性较差,只有2.3,4.0~4.4兼容,其他Android版本不兼容或未测试,详细可以去dexposed的github项目主页查看,而andfix则兼容2.3~6.0,所以就拿这个项目来实现增量更新吧。至于bsdiff,只是阅览了一下,还没研究过。

首先 git clone github https://github.com/alibaba/AndFix,将andfix项目下载下来,Android studio可以在build.gradle里导入andfix,

compile 'com.alipay.euler:andfix:0.3.1'
但是我是使用module的方式添加andfix,这样可以直接查看编辑源码,而且直接gradle导入的话还有个问题,后面再说。

andfix项目里有sample,导入也行,自己新建也行,我是自己新建项目,接着导入andfix作为module,demo里就两个类,mainactivity和myapplication


andfix里有些文件夹不用导入的,例如tools,doc等,记得新建jniLibs文件夹,libs里的so文件移到jniLibs里。

public class MainApplication extends Application {
    private static final String TAG = "euler";

    private static final String APATCH_PATH = "/out.apatch";

    private static final String DIR = "apatch";//补丁文件夹
    /**
     * patch manager
     */
    private PatchManager mPatchManager;

    @Override
    public void onCreate() {
        super.onCreate();
        // initialize
        mPatchManager = new PatchManager(this);
        mPatchManager.init("1.0");
        Log.d(TAG, "inited.");

        // load patch
        mPatchManager.loadPatch();
//        Log.d(TAG, "apatch loaded.");

        // add patch at runtime
        try {
            // .apatch file path
            String patchFileString = Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + APATCH_PATH;
            mPatchManager.addPatch(patchFileString);
            Log.d(TAG, "apatch:" + patchFileString + " added.");

            //这里我加了个方法,复制加载补丁成功后,删除sdcard的补丁,避免每次进入程序都重新加载一次
            File f = new File(this.getFilesDir(), DIR + APATCH_PATH);
            if (f.exists()) {
                boolean result = new File(patchFileString).delete();
                if (!result)
                    Log.e(TAG, patchFileString + " delete fail");
            }
        } catch (IOException e) {
            Log.e(TAG, "", e);
        }

    }
public class MainActivity extends Activity {
    private static final String TAG = "euler";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        toast();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        android.os.Process.killProcess(android.os.Process.myPid());
    }
    
	//旧方法,1.apk
private void  toast () { Toast. makeText ( this,  "old" Toast. LENGTH_SHORT ).show() ;   }}


刚刚说的直接在gradle里导入andfix会有个问题,是在原来的项目中,加载一次补丁后,out.apatch文件会copy到getFilesDir目录下的/apatch文件夹中,在下次补丁更新时,会检测补丁是否已经添加在apatch文件夹下,已存在就不会复制加载sdcard的out.apatch。

原来的addpath方法

public void addPatch(String path) throws IOException {
    File src = new File(path);
    File dest = new File(mPatchDir, src.getName());
    if(!src.exists()){
        throw new FileNotFoundException(path);
    }
    if (dest.exists()) {
        Log.d(TAG, "patch [" + path + "] has be loaded.");
        return;
    }
    FileUtil.copyFile(src, dest);// copy to patch's directory
    Patch patch = addPatch(dest);
    if (patch != null) {
        loadPatch(patch);
    }
}
修改后,判断apatch下的out.apatch存在即删除掉,重新复制加载sdcard下的out.apatch


public void addPatch(String path) throws IOException {
    File src = new File(path);
    File dest = new File(mPatchDir, src.getName());
    if (!src.exists()) {
        throw new FileNotFoundException(path);
    }
    if (dest.exists()) {
        Log.d(TAG, "patch [" + src.getName() + "] has be loaded.");
        boolean deleteResult = dest.delete();
        if (deleteResult)
            Log.e(TAG, "patch [" + dest.getPath() + "] has be delete.");
        else {
            Log.e(TAG, "patch [" + dest.getPath() + "] delete error");
            return;
        }
    }
    FileUtil.copyFile(src, dest);// copy to patch's directory
    Patch patch = addPatch(dest);
    if (patch != null) {
        loadPatch(patch);
    }
}


还有源码混淆

-optimizationpasses 5                                                           # 指定代码的压缩级别
-dontusemixedcaseclassnames                                                     # 是否使用大小写混合
-dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar
-dontpreverify                                                                  # 混淆时是否做预校验
-verbose                                                                        # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*        # 混淆时所采用的算法

#重要,別忘了這些,不混淆andfix包,不混淆native方法
-dontwarn android.annotation
-dontwarn com.alipay.euler.**
-keep class com.alipay.euler.** {*;}
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
    native <methods>;
}

接着打包1.apk,

然后修改mainactivity的toast(),打包2.apk

//修改Toast內容,2.apk
private void toast() {
    Toast.makeText(this, "new", Toast.LENGTH_SHORT).show();
}

cmd输入命令,具体参数看usage

apkpatch.bat -f new.apk -t old.apk -o output1 -k suning.keystore -p Suning1234 -a suning -e Suning1234 【完整命令】


如无错误,编译后会生成一个apatch文件,改名成out.apatch


安装打开1.apk

关闭app,将out.apatch放sdcard根目录后,重新打开app,toast方法改变了


ps:

1. 这里只是简单的测试了一下,没有复杂的功能,而且andfix不支持布局资源等的修改。

2. github主页的issues反应说Android4.0.4,以及5.0以上版本会crash,不过我使用了两个虚拟机,genymotion的4.2和5.0虚拟机,没有错误,其他请自测

3. 使用了apk加固时(360加固,百度加固等等),发现在加固前要先apkpatch制作补丁,不能使用加固后的apk制作,否则补丁无法使用,但是在加固前制作的补丁可以很容易的被反编译出源码




DEMO:  http://download.csdn.net/detail/yaya_soft/9390182

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值