最近热更新热修复的功能在安卓应用上愈加火热,终于个人产品也提出了相应的需求。java
通过两天的研究,搞定了这个功能,在这里还要多谢大神们的博客,大神们的原理分析很到位,不过对于我来讲最大的障碍仍是在git的使用、打jar包出现的一些错误上,因此在这里写出具体些的实现步骤,但愿能够帮到那些和我水平差很少的小虾。android
热更新的框架有不少,好比AndFix、HotFix、Dexposed以及Nuwa,在考虑兼容性和功能需求以后我仍是选择了Nuwa,由于这个框架能够新增类和字段,而且兼容到Android6.0系统。git
如今市面上的热更新框架基本原理都是classloader,也就是类加载器,这也就限制了咱们不能够修改资源文件,如图片布局等,有这方面需求的小伙伴还要想其余办法,好比动态布局。github
咱们先来讲下准备工做,首先你的开发工具必须是Android Studio,由于在打jar包时须要使用.gradle文件。其次电脑上要有一个本地的git库,以方便管理新旧版本,使用git命令较为方便,要下载nuwa库,而且user library到你的项目中,不会这个步骤的同窗请自行百度,在这里推荐一个github上的项目,里面有集成好的nuwa库。windows
https://github.com/jasonross/Nuwa服务器
假设咱们已经建立好一个项目,而且成功集成nuwa,如今咱们须要一个git,若是没有安装git的同窗请按照下面这篇教程安装,这篇教程通俗易懂。app
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000框架
git安装成功后,要新建一个本地版本库,选择一个合适的文件路径,输入如下git命令:ide
mkdir hotfix 是建立名为hotfix的本地版本库,cd hotfix是定位到版本库,pwd是输出版本库位置,若是你是在windows系统上使用,为了不不可测问题,请保证路径中没有特殊符号及中文。工具
建立好库后要使用命令将其变成git可管理的版本库:
建立成功后,会发现文件夹中出现一个.git文件,若是你的看不到,那多是由于这个文件是隐藏的,使用ls -ah
命令试试看。
版本库建立成功了,如今咱们要作的就是将刚刚建立的项目导入到版本库中,拷贝你的项目到hotfix文件夹中,而且使用如下命令:
git add 后面跟着的是你的项目名称,在add过程当中会出现一系列waning警告,不要理,只要不出error就好。add成功后,再提交一次代码,若是没有问题就你的项目就导入成功了:
提交过程当中又会出现一系列warning,不用理。这里须要注意的是-m后面是你每次提交的注释,不可为空,为了方便之后维护,但愿你们能够写清本次提交缘由。
成功将项目导入,下面咱们就要开始写代码了,若是你的项目是从刚刚推荐的github上拉下来的,那你项目中应该有完整代码,不是的童鞋请跟我一步步完成代码。
热更新的原理大概就是从服务器拉取一个补丁文件,而后用类加载器加载这个补丁中的类,若是咱们想要实如今项目开始时就加载出这个补丁文件,那么加载补丁的操做就要放在Application类中实现,代码以下:
import android.app.Application; import android.content.Context; import android.os.Environment; import cn.jiajixin.nuwa.Nuwa; public class NuwaApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); Nuwa.init(this); Nuwa.loadPatch(this, Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch.jar")); } }
很简单,nuwa框架已经封装好了不少操做,咱们只须要调用就好,loadpatch方法中的参数是补丁文件的位置,应该从服务器动态获取文件,并存储到sdcard指定项目专用目录,在这里咱们是测试demo,就简单的固定好jar文件位置,sdcard根目录。在这里提醒一下粗心的同窗,不要忘记在Manifest文件中配置Appliction。
其余只须要在MainActivity中显示要输出的文字,这里咱们将文字单放在一个类中,以便改变:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; import cn.jiajixin.nuwasample.Hello.Hello; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.textview); textView.setText(new Hello().say()); } }
public class Hello { public String say() { return "hello world"; } }
好了,代码已经写完了,是否是很简单?如今要注意,下面是一些核心步骤,这是在其余文案上找不到的。
咱们要在刚刚创建的本地版本库上创建一个bugfix分支,hotfix文件夹中打开git,并输入如下命令:
git branch bugfix 是新建一个名为bugfix的分支,git checkout bugfix是转到这个分支下,好了,如今对比如下两个分支的代码,应该是如出一辙的,如今使用命令:git checkout master切换回主分支。
使用android studio运行项目到手机上,成功运行以后,会在项目的目录下建立一个nuwa文件夹,若是你是本身建立的项目,那么路径应该是app/build/outputs/nuwa,若是你是导入github上的项目,路径应该是sample/build/outputs/nuwa,将nuwa文件夹拷贝到一个位置,好比桌面,个人是C:\Users\thinkpad\Desktop\nuwa,这个地方你们要注意,每一个人拷贝的位置不一样,一会使用时路径必定要匹配。
如今使用git checkout bugfix命令切换到bugfix分支上,修改Hello类下面的输出字符串,以下:
public class Hello { public String say() { return "hello world I'm hotfix"; } }
改好以后咱们就要经过git命令调用.gradle来打一个jar包,千万注意,不要运行bugfix分支上的项目。
若是你是本身新建的app,要在项目中新建一个名为extras的文件夹:
在文件夹中有两个配置文件,一个是名为hack的空java类,另外一个文件里面写好了一段使用dx封装jar包的命令:
配置好这两个文件后,再在hotfix中开启git,在git中输入./gradlew clean nuwaQihooDebugPatch -P NuwaDir=C:/Users/thinkpad/Desktop/nuwa,这里有两点须要注意,NuwaDir=后面跟着的路径就是刚刚master分支运行项目时,生成的nuwa文件夹,具体路径要看你们拷贝的地址。还有就是由于这个命令是调用.gradle文件,咱们的版本库是两层文件夹,须要cd进入到Nuwa项目文件夹中运行该命令:
运行成功后你会在你想项目目录下看到一个名为patch.jar的文件,若是你是新建的项目,具体路径应该为app\build\outputs\nuwa\qihoo\debug\patch.jar,若是你是从github上拉下来的项目,路径应为sample\build\outputs\nuwa\qihoo\debug\patch.jar。
将上面生成的jar文件导入到手机sdcard文件根目录,你能够选择经过电脑拷贝或者使用安卓命令:
adb push E:hotfix\Nuwa\app\build\outputs\nuwa\qihoo\debug\patch.jar /sdcard/
你们写了这么久,终于到了收获的时候,如今先退出刚刚在手机上安装的master分支上的项目,完全退出,杀死进程。而后再从新进入,有没有惊喜的发现以前的"hello world"变成了咱们修改的"hello world I'm hotfix"?这就实现了补丁方式的热更新,并且使用nuwa框架是能够新建类的哦,虽然不能更改资源文件,可是配合动态布局使用仍是能实现大部分需求的。
好了,相信如今你们对nuwa的热更新流程已经了解的差很少,写这篇博客很用心,由于本身的研究热更新的时候遇到了不少头大的问题,因此想要分享给那些和我同样正在研究或将来要研究这个功能的人,若是你们有要补充的或者哪一个步骤遇到问题,欢迎留言,我会及时回复。