native如何热更新,必须知道的一个shell命令

开张早先,先讲八个和谐支付中的一个小片头曲:

奥迪Q5N的热更新和weex的热更新分化,weex是足以一贯访谈远程服务器的,有新本子的时候一直改变服务器上的文书就能够,不过锐界N不行,奔驰M级N的热更新是内需更交换一下地方置文件,所以景逸SUVN的热更新供给越多的论断。

后日周天,iOS版 App 周大器晚成提交,周一核实通过上架,很给力.可是,凌晨11:30的时候,运转就影响某些页面有四个很引人侧指标主题材料,页面没有办法拉到头部,部分音讯显示不全;那三个页面是基于react-native写的,项目中自身已经有了热更新的相干机制;原因相当的轻便,13:00左右,撤除难点,发了七个补丁,测验蒙受自测达成;补丁发给Leader,他得以付出到线上;出去吃饭,13:00 回来午间休息;14:00,Leader回到工位,补丁提交到线上;确认补丁生效,难题消除.

原理

卡宴N热更新的规律是依据MainAppliction中new ReactNativeHost下的getJSBundleFile方法,它私下认可重临index.android.bundle.js的公文路线,大家供给做的就是去替换它。所以它的步骤正是: 决断是或不是热更新 -> 下载zip包(zip包缩短带宽卡塔尔 -> 解压 -> 完事。热更新正是那般的简约。

   @Nullable
   @Override
   protected String getJSBundleFile() {
     // 判断权限
     if (!new RuntimePermissions(context).check(Manifest.permission.WRITE_EXTERNAL_STORAGE))
       return super.getJSBundleFile();

     File file = new File (FilePath.BUNDLE_PATH);
     if(file != null && file.exists()) {
       return FilePath.BUNDLE_PATH;
     } else {
       return super.getJSBundleFile();
     }

   }

无须嗤笑说,流程能够更优化,消弭的难题更快,这提到到另三个话题,改日有心理再聊.

判断是或不是热更新

我们须要在进入app页面时发送互连网乞请去开展热更新推断,剖断热更新的标准有多个:大器晚成,本地原生版本大于或等于网络央浼的原生版本。二,本地球热能更新版本小于互连网央浼的热更新版本。那五个原则还要创建则张开热更新下载。第二个尺码是为着限定不让原生和热更新同临时间触发,事实上原生更新是回顾热更新的。本地的原生版本能够透过改过AndroidManifest.xml的meta-data来决断。而地面包车型客车热更新版本是不可能那样的,所以自个儿在bundle.zip中参预一个version.txt来调整热更新版本,每便热更新后version.txt都加风流倜傥,在android中读取这么些文件来赢得本地热更新版本,然后再去和网络央求的比对就能够看清是不是供给热更新了。

图片 1

流程图

若果依照未有热更新技巧的化解流程,大致会是: 11:30 发掘难点,13:00 消除,确认测量检验情状生效;生成测量试验包,上传 提交;人品好的话,能够走火急检查核对;3~5天后,难点修复.3~5天的调查期,有人以为相当短,有人已经习以为常.

下载

    public static void downloadFile(final Context mContext, String url) throws Exception {
    AsyncHttpClient client = new AsyncHttpClient(getSchemeRegistry());
    client.get(mContext, url, new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            BufferedOutputStream bos = null;
            FileOutputStream fos = null;
            File file = null;
            try {
                file = new File(FilePath.ZIP_LOCAL_PATH);
                fos = new FileOutputStream(file);
                bos = new BufferedOutputStream(fos);
                bos.write(responseBody);
            } catch (IOException e) {
                e.printStackTrace();
            }
            File zipFile = new File(FilePath.ZIP_LOCAL_PATH);
            File file_unzip_path = new File(FilePath.LOCAL_PATH);
            if (!file_unzip_path.exists()) {
                file_unzip_path.mkdir();
            }
            try {
                UnZipFolder(zipFile, FilePath.LOCAL_PATH);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {
            Toast.makeText(mContext, "下载失败", Toast.LENGTH_LONG).show();
        }
    });
}

下载这里要求提到的三个点是: https的下载须要对其ssl认证,反正也是第一次碰到,网络找的多个方法.

public static SchemeRegistry getSchemeRegistry() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));
        return registry;
    } catch (Exception e) {
        return null;
    }
}

小片头曲而已,看看就好.小编只是想让大家领会,react-native本人,或者对您的业务,确实是三个很有意义的工具,如此而已.许三人,也是承认react-native 的股票总值的,不过只怕并不曾在本身的档次中利用,而从不选拔的源委,相对后生可畏部分原因,是很难明白.从自身眼下的进行来看,未有叁个可以预知同期自由通晓Native和react栈的技艺职员存在,一个手艺组是很难有一点都不小希望把react-native应用起来的.因为中期,必得有 native 能力栈的人,去增补一些或许用react相比较难达成的效果;中早先时期,又不得不 有 react 手艺栈的人,来浓重地利用react本人的技能栈,来加强成本作用,比如redux的选择等.

解压

public static void UnZipFolder(File f, String outPathString) throws Exception {
    ZipInputStream inZip = new ZipInputStream(new FileInputStream(f));
    ZipEntry zipEntry;
    String  szName = "";
    while ((zipEntry = inZip.getNextEntry()) != null) {
        szName = zipEntry.getName();
        if (zipEntry.isDirectory()) {
            //获取部件的文件夹名
            szName = szName.substring(0, szName.length() - 1);
            File folder = new File(outPathString + File.separator + szName);
            folder.mkdirs();
        } else {
            Log.e(TAG,outPathString + File.separator + szName);
            File file = new File(outPathString + File.separator + szName);
            if (!file.exists()){
                Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
                file.getParentFile().mkdirs();
                file.createNewFile();
            }
            // 获取文件的输出流
            FileOutputStream out = new FileOutputStream(file);
            int len;
            byte[] buffer = new byte[1024];
            // 读取(字节)字节到缓冲区
            while ((len = inZip.read(buffer)) != -1) {
                // 从缓冲区(0)位置写入(字节)字节
                out.write(buffer, 0, len);
                out.flush();
            }
            out.close();
        }
    }
    inZip.close();
}

雷同的例证,笔者是见过部分,有死在 node 情状陈设的,有卡在 native 原来就有利用不也许集成的,当然,也是有卡在不明白 怎么着出手使用 react-native的 的热更新技巧的.

问题

android6.0以上(包涵6卡塔尔国都亟需动态授权,热更新需求的权杖是

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

动态授权会促成的二个标题是:当你安装完app后,当时您从未给app授权,可是已经济检察测到必要热更新,下载完后解压就须要android.permission.WLANDITE_EXTERNAL_STORAGE这么些权力,没有的话会crash,所以供给判断的是不曾这些权力就不让他下载。

// 判断是否有权限
if (permission.check(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    new UpdateChecker().check(this);
}

动态授权还或者有贰个标题是:你的app已经热更新过,未来你把它卸载掉,再重新装的时候,就算不会触发热更新,但是那时候你手提式有线电话机上曾经有热更新过的文书夹,这时候app会直接去拜会热更新的文本夹,又是因为未有授权,所以报错,crash。这里大家同样须要做个决断是不是有权力。

   @Nullable
   @Override
   protected String getJSBundleFile() {
     // 判断权限
     if (!new RuntimePermissions(context).check(Manifest.permission.WRITE_EXTERNAL_STORAGE))
       return super.getJSBundleFile();

     File file = new File (FilePath.BUNDLE_PATH);
     if(file != null && file.exists()) {
       return FilePath.BUNDLE_PATH;
     } else {
       return super.getJSBundleFile();
     }

   }

都以泪呀!!!那多少个坑。

热更新,本人机制的安排,英特网钻探的也可能有后生可畏部分,三个最简化的模型是: react-native 是依照 main.bundle 加载的; main.bundle 自己是多少个文书夹;每一次展开app,都去查看有无最新的 main.bundle,有就下载更新当羊眼半夏件就能够.blablalba.....会涉及到超多细节难点,但本人相信,三个搞Native开荒的人,是都足以独立扫除的.

最终优化

1.热创新的进程开一个子线程去消除。

  1. 增量更新,不供给每一遍都去下载贰个后生可畏体化的bundle.zip,就算超小,可是能省则省嘛
  2. bundle.zip中的version.txt自动加生机勃勃。

github地址

个人博客

简书地址

今天,要说的标题是, main.bundle 里,是饱含全数的财富文件的,今后发补丁,笔者是全部 把新型的 完整的 main.bundle 发出去了,本身压缩后,不到 1M,和多少个大图片也大都,基本客商无感;但自己未来是内需逐步把原生的有个别代码,逐步迁移到 react 来的,此中的相比较根基也正如首要的一步是,把 原先Native代码中的财富文件,迁移到 main.bundle 里,使用 main.bundle 处理.

可以吗,不要又作弄作者说, main.bundle 里,是不会卷入未利用的图样的; 小编确实是,手动把图片放到 main.bundle 里的,里面新建个 native 文件夹,用于放置 native 代码必要的片段财富,那样 native 代码,也足以部分运用 热更新的逻辑了.今后品种中,热更新的逻辑有两部分: JSPatch 和 react-native,小编是由此 二个 补丁类型字段来分别的.借使为 native 和 react单独分开设计 热更新机制,用脑筋想都心累--可能说,有一些太懒,有些代码,还不想去动.--别怪作者话多,那是三个很有价值的计划,倘若您也是依照Native来混编react-native的话,或然有种听君一席话共君一夜话胜读十年书恐怕英雄所见略同的以为,即便本人只在iOS上试验过.

有一些跑题了,再度准备回归正题.提起四个main.bundle 相比较diff出贰个差集,互连网探究的超级多,大家搜下,勉强有个别有个别能够借鉴的.index.jsbundle文件自身的diff,小编有时不思谋,觉得没须求,压缩后 唯有 300 k的东西,还不值得本身去改热更新的实今世码,而且 jsbundle 本身的建制一贯在变,比方方今的 jsbundle 都有个了二个对应的 index.jsbundle.meta 文件,原本的设计,可能是有题指标;我明天要斟酌的只是,文件级其他相比较操作--轻巧说,正是找到八个公文夹中不平等的公文,放到第五个文件夹中,就那样.

有一些人会讲,能够比较 md5 什么的--当然也是能够的;可是,作者今后不想去知道那一个原理,可能说,原理笔者是理解的,作者不想去实现这段代码,没写过,何人知道有啥样坑呢?举例,文件目录布局怎么着保存什么的.小编想驾驭的是,有未有大器晚成种简易的法子,三个ctrl+c ctrl+v,即可直接获取答案难题的点子?

当然是意气风发对, shell 脚本嘛,什么不得以搞,如下:

rsync -aHxv --progress  --compare-dest=$(pwd)/main_old.bundle/ $(pwd)/main_new.bundle/ $(pwd)/main.bundle/
find $(pwd)/main.bundle/ -type d -empty -delete

好吧,脚本自身确实轻松,只是自身本身刚刚须求运用,google出来,再享受给大家而已.作者信赖,一个纵深应用 react-native 到花色中,而且相比较信任其能够热更新性格的人,是早晚有其风流倜傥须要的;何况,作者也精通,他们杰出一些,要么无法确切地问出难题,要么傻傻地团结去写 文件夹比较的代码...小编不可能说那异形,作者想说的是: 编制程序这种东西, 多学点总是好的.此处奉上原始google参照他事他说加以考察链接,与原本答案有细微不相同,懂shell的人,一眼就看的出来,不懂的,估摸尽管搜到答案,也许有相当的大可能率弄不出去结果.链接奉上:

再有就是,react-native 作者很看好它,即便它很有望以往把自身自身的事情给砸了.大势所趋,不能;浪潮之下,要么驾车,要么被压平成路,硬着头皮上啊,万意气风发咱们现在都用那个搞了呢...

本文由明仕msyz手机版发布于家居装修-蜗牛装饰,转载请注明出处:native如何热更新,必须知道的一个shell命令

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。