参考资料:http://blog.csdn.net/qxs965266509/article/details/49802429
http://blog.csdn.net/yaya_soft/article/details/50460102
http://www.jianshu.com/p/479b8c7ec3e3
http://blog.hwangjr.com/2016/03/02/Android-HotFix%E6%96%B9%E6%A1%88/
随着开发需求的不断迫切,目前开源已经涌现了很多Hot Fix项目,但是从方案上来说,主要是基于rovo89/Xposed的alibaba/dexposed;以方法hook,从Field切入的AndFix;Dex分包的Nuwa。而相同原理的不同实现有很多,这里就不再累赘。这三个实现原理截然不同,各有各自优缺点,让我们走近这几个方案。
本文只实现了AndFix来实现热修复功能
1.首先添加依赖关系
compile ‘com.alipay.euler:andfix:0.3.1@aar’
2.然后在Application的onCreate方法中初始化AndFix(自定义BaseApplication,继承Application)
public class BaseApplication extends Application { private String appVersion; private PatchManager patchManager; private static final String APATCH_PATH = "/out.apatch"; private String patchFile; @Override public void onCreate() { super.onCreate(); try { appVersion = getApplicationContext().getPackageManager(). getPackageInfo(getPackageName(), 0).versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } // 初始化patch管理类 patchManager = new PatchManager(this); // 初始化patch版本 patchManager.init(appVersion); // 加载已经添加到PatchManager中的patch patchManager.loadPatch(); try { //自动获取路径 //patchFile = Environment.getExternalStorageDirectory() //.getAbsolutePath().concat(APATCH_PATH); //暂时写固定路径,测试用 patchFile ="/sdcard" + APATCH_PATH; //添加到patch patchManager.addPatch(patchFile); } catch (IOException e) { e.printStackTrace(); } } }
3.在需要的地方调用addPatch方法加载新补丁,如第2步,比如在下载补丁文件后调 用这个方法。
4.修改有bug的地方,分别打出apk包,命名为old.apk,new.apk如下:
public class MainActivity extends AppCompatActivity { private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.textview); mTextView.setText(R.string.old_name); } }
此时 TextView显示的字为“这是old app”,打出一个包,改名字为old.apk。
将MainActivity的修改为:
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textview);
mTextView.setText(R.string.new_name);
}
}
此时 TextView显示的字为“这是and_fix app”,打出一个包,改名字为new.apk。
5.关键一步,生成apatch文件,也就是补丁文件,用到的是apkpatch-1.0.3工具,这这一步,要把第四步生成的两个apk和签名文件要放到apkpatch的同一文件夹下,如图:
然后在终端运行命令:前提是已经定位到此目录下,否则会报 commond not found
./apkpatch.sh -f new.apk -t old.apk -o ./ -k andfix.jks -p 1q2w3e4r -a 123456 -e 1q2w3e4r
说明:
-f <new.apk> :新版本
-t <old.apk> : 旧版本
-o <output> : 输出目录
-k <keystore>: 打包所用的keystore
-p <password>: keystore的密码
-a <alias>: keystore 用户别名
-e <alias password>: keystore 用户别名密码
运行完命令后:
将后缀名为.apatch的文件改下名字,为out.apatch,然后拷贝到手机中的sd的根目录下,重新安装old.apk,就会看到页面如下:
注意 !!前提要在Manifest中注册相关权限
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>