Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

В предыдущие годы, в целом большая разница по сравнению с мобильной сетевой среде в настоящее время, в сочетании с зарядами трафика относительно высока, поэтому каждый раз , когда мы выпускаем новую версию некоторых пользователей обновить не очень позитивно, что привело к новой версии скорость обновления это не является высоким. И Google Для того, чтобы решить эту проблему, Smart App Update, а именно добавочные обновления (также известные как дифференциальное обновление).
Хотя в настоящее время сетевой среды была значительно улучшена, но бесспорный факт , что применение все больше и больше, поэтому дополнительные обновления по - прежнему присутствует в пакете обновления APP решения является слишком большим для эффективной программы. Сегодня мы будем говорить о дополнительных обновлениях.

1. Что такое дополнительные обновления?

Ключ лежит в том, как дополнительных обновлений понимания приращений термина. Обычно мы думаем о процессе развития, часто, чтобы изменить код сегодня, вчера, на основе, обновление приложения схоже: часто модифицированы на старую версии приложения. Казалось бы, что дополнительные обновления только обновление измененных мест на основе оригинального приложения, оставаясь нетронутым.

По сравнению с оригинальной APK каждое обновление необходимо загрузить полный подход пакета, выгоды от этого очевидны: где каждого изменения всегда относительно невелико, так много обновлени размер пакета будет меньше. Например, «Учитель сказал» объем инсталляционного пакета составляет около 6 метров, если не инкрементального обновление, пользователи должны загрузить каждый пакет установки обновления вокруг около 6 метров, а также использование таких дополнительных обновлений необходимо только скачать программу около 2 м в пакет обновления может быть, по сравнению с оригиналом подход значительно сокращает время ожидания для пользователей, чтобы загрузить.

2. Каковы преимущества дополнительных обновления?

Дифференциальный преимущество

  • Размер очень мал
  • Безопасность - должна быть конкретный узел, чтобы обновить
  • Весь пакет легче контролировать относительно

3. Почему снизить затраты на модернизацию

Например , есть старая версия APK 5M, есть новая версия 8M, обновление может быть только частью 3М (Следует отметить, что размер полученного разностного субподрядчика не является простым вычитание, потому что на самом деле необходимо включить контекстный материал) выгоды от использования разницы очевидно обновления,
то вам не нужно , чтобы загрузить полный файл 8M нужно только загрузить обновления раздела на баллончике, и обновить некоторые из них могут быть 3,4м, может в значительной степени уменьшить потери трафика.

4. инкрементного обновления принципа

Инкрементальный принцип обновления очень прост, просто говоря, это так называемое обновление патча (патч, чтобы найти новые и старые версии не то же самое места (этот процесс также называется дифференциалом), то не то же самое место, извлеченным с помощью алгоритма ), также известный как к югу от разности. Клиент определяется, когда обновление, просто скачайте разницу местных субподрядчиков, субпоставщиков и разница в локальной установки пакета слияния, чтобы сформировать новую версию пакета установки, а затем выполнить файл установки, чтобы проверить через. Локальные пакеты установки в настоящее время установлены экстракцию APK были применены.

Демонстрация: разница генераторного пакетизирована в сочетании ,
как показано ниже:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

Вопрос теперь заключается в том , чтобы создать разницу разница субподряда и субподрядных слияния. Здесь мы используем библиотеки с открытым исходным кодом , bsdiffчтобы решить эти две проблемы. Во- первых , мы покажем вам разницу между формированием и укреплением субподрядчиками.

Скачать bsdiff_win_exe.zip, доставать местные. Фигура следующим образом:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

Тогда мы играли предполагается, первый пакет установки old.apk. После внесения изменений в исходный код, а затем воспроизводить новый инсталляционный пакет new.apk. Здесь old.apk эквивалент старой версии приложения, что эквивалентно new.apk новой версии приложения. Далее, мы используем bsdiff для создания разницы субподрядных patch.patch.

Генерации разница суб

Выше и new.apk old.apk bsdiff декомпрессии в каталог, а затем выполнить команду bsdiff old.apk new.apk patch.patch в консоли, погоди может генерировать разность суб patch.patch следующим образомTencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

6. Объединение бедных субподрядчика

Комбинированное old.apk и patch.patch, генерирует новый инсталляционный пакет new.apk. Пока совмещенной new.apk здесь и играть над собой из new.apk, то мы можем думать о нем, как новая версия, нам нужно установить пакет.

Давайте посмотрим, как объединить. Old.apk и patch.patch в папку bsdiff до слияния

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления
Затем выполните команду bspatch old.apk new.apk patch.patch, погоди после слияния будет иметь возможность видеть из new.apk следующим образом:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

不出意外,合并而来的new.apk应该和我们自己打出来的new.apk是一模一样的,这可以通过验证两者的md5来认定。
我们已经弄明白增量更行是怎么一回事。下面,我们就以“师父说”为对象进实践一把。

7.实践:让师父说支持增量更新

客户端支持增量更新总体和上面的演示差不多,唯一的区别在于客户端要自行编译bspatch.c来实现合并差分包,也就是所谓的ndk开发,这里我们首先要下载bsdiff的源码以及bszip的源码,以便后面使用。在as中如何进行ndk开发不是本文的重点。

7.1.编写BsPatchUtil类 BsPatchUtil中只有一个natvie方法patch(String oldApkPath,String newApkPath,String patchPath)用于实现增量包的合并:

public class BsPatchUtil {
    static {
        System.loadLibrary("apkpatch");
}

public static  native int patch(String oldApkPath, String newApkPath, String patchPath);

7.2.编写C代码

在实现BsPatchUtil之前,我们需要将bspatch.c以及bzip的相关代码拷贝到jni目录下(bzip只保留.h头文件和.c文件)。并将bspatch.c中的main()方法名修改为executePatch(),并且修改其中bzip的引入头为#include "bzip2/bzlib.h".目录结构如下:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

注意:上图当中的em.c是一个空文件,用来避免在window下编译产生的未知错误。

接下来我们就可以在bspatch_util.c中实现相关的代码了:


#include "com_closedevice_fastapp_util_BsPatchUtil.h"

JNIEXPORT jint JNICALL Java_com_closedevice_fastapp_util_BsPatchUtil_patch
        (JNIEnv *env, jclass clazz, jstring old, jstring new, jstring patch){
        int args=4;
        char *argv[args];
    argv[0] = "bspatch";
    argv[1] = (char*)((*env)->GetStringUTFChars(env, old, 0));
    argv[2] = (char*)((*env)->GetStringUTFChars(env, new, 0));
    argv[3] = (char*)((*env)->GetStringUTFChars(env, patch, 0));

    //此处executePathch()就是上面我们修改出的
    int result = executePatch(args, argv);

    (*env)->ReleaseStringUTFChars(env, old, argv[1]);
    (*env)->ReleaseStringUTFChars(env, new, argv[2]);
    (*env)->ReleaseStringUTFChars(env, patch, argv[3]);

    return result;
}

至此,大部分工作已经完成了。配置app moudle中的build.gradle中添加ndk配置

defaultConfig {
        applicationId "com.closedevice.fastapp"
        minSdkVersion 14
        targetSdkVersion 24
        versionCode 1
        versionName "1.0.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //ndk配置
        ndk{
            moduleName "apkpatch"
            abiFilters "armeabi", "armeabi-v7a","x86"
        }
    }

接下来,我们编译试试(ndk环境的配置这里不做说明,自行配置即可),不出意外会遇到以下错误:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

该问题的解决方法也非常简单,注释掉对应文件的main()方法即可。重新编译,不出意外没什么问题了。接下来,我们就需要在合适的地方合并差分包了。

7.3.合并差分包

上面的过程做完之后,就可以通过BsPatchUtil.patch()来合并当前安装包和差分包了。

Здесь мы предполагаем, что разница между субподрядчиками были загружены с сервера на локальный.

Первый взгляд на то, как получить текущий пакет установки. Мы установили приложение, как правило, при данных / приложении, вы можете получить свой путь через код ниже:

public static String getApkInstalledSrc(){
        return BaseApplication.context().getApplicationInfo().sourceDir;
    }

Далее могут быть объединены с помощью BsPatchUtil.patch (String oldApkPath, Струнный newApkPath, строка pathPath). Две вещи, чтобы отметить здесь:

  1. Объединенные местные рекомендации по внешнему хранению (SDCard), которые
  2. Процесс слияния отнимает много времени, он должен быть помещен в суб-нить.

7.4. Установка

Любой пакет обновления после загрузки завершается первое, что нужно сделать, это выполнить контрольную сумму MD5, чтобы подтвердить, что пакет обновления загружаются с формальным способом. Кроме того, для пакета обновления после слияния, то первое, что нужно сделать, это выполнить контрольную сумму MD5, после проверки, а затем установить его:

 public static void installAPK(Context context, File file) {
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

До сих пор, инкрементальное обновление было завершено. Теперь может инкрементный пакет и установить пакет после слияния удалено.

Генеральный код следующим образом:

private void smartupdate() {
        Observable.create(new Observable.OnSubscribe<File>() {
            @Override
            public void call(Subscriber<? super File> subscriber) {
                //定义生成的新包
                File newApk = new File(Environment.getExternalStorageDirectory(), "newApk.apk");

                //假设patch.patch文件已经下载到sdcard上,切已经校验通过
                File patch = new File(Environment.getExternalStorageDirectory(), "patch.patch");

                if(!patch.exists()){
                    subscriber.onError(new IOException("patch file not exist!"));
                    return;

                //合并差分包
                BsPatchUtil.patch(OSUtil.getApkInstalledSrc(), newApk.getAbsolutePath(), patch.getAbsolutePath());
                if (newApk.exists()) {
                    subscriber.onNext(newApk);
                    subscriber.onCompleted();
                    patch.delete();
                }else{
                    subscriber.onError(new IOException("bspatch failed,file not exist!"));
                }

            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        showDialog("正在应用差分包");
                    }
                })
                .subscribe(new Subscriber<File>() {
                    @Override
                    public void onCompleted() {
                        hideDialog();
                    }

                    @Override
                    public void onError(Throwable e) {
                        hideDialog();
                        LogUtils.d(e.getMessage());
                    }

                    @Override
                    public void onNext(File file) {
                        OSUtil.installAPK(getActivity(),file);
                    }
                });

    }

8. постепенные недостатки обновления

Хотя инкрементальное обновление позволяет эффективное решение проблемы чрезмерного пакета обновления, но следующие проблемы существуют:

8.1. Клиент и сервер необходимо добавить соответствующую поддержку. Каждый релиз, сервер должен передоверять все предыдущие версии старшего поколения , соответствующая разница, и возвращает соответствующий пакет обновления на основе запроса на стороне клиента, обслуживание будет относительно сложным. Клиент должен сделать для бедных субподряда более детальной проверки, во избежание ошибок, кроме того, клиент должен иметь возможность определять текущее использование на основе дополнительных обновлений или полного сервера обновлений для обновления коммутатора.
8.2. Разница Apk между пакета слишком мал, например , как показано ниже 2 м, разница генерируется в это время все еще существуют сотни суб-к, на этот раз с использованием дополнительных обновлений больше вреда , чем пользы, и после формирования разности суб-процесс занимает очень много времени , вместе взятых. Кроме того, изменения между версиями очень большое, как правило , это время , чтобы изменить большую версию блага, например, от V 1.0.0 до 2.0.0, на этот раз с использованием полного обновления также хорошо.

В Мастер говорит, были добавлены к основному кода, самообладания практике. Результаты таковы:

Tencent интервью: расширяющее обновление Почему обновление для снижения затрат, принцип расширяющего обновления

рекомендация

отblog.51cto.com/14332859/2424574