android 增量更新

android增量更新

android 4.1开始 google引入了应用程序的增量更新。增量更新的原理实际上是使用服务器最新的apk进行对比,并得到罪行的差分包,当应用程序需要更新是,下载差分包就好了,通过它和现在本机上的版本形成一个新的apk

服务端形成差分包

拆分包可以在服务端生成,用的是在网上找的一个例子
SmartAppUpdates-master
当然,我没有编译java服务端的例子,又在网上找了某个大神打包好的项目,直接在本地就直接能打包好apk的拆分

这是关于拆分的详细介绍,我就是在这篇博客上学习怎么增量更新的
https://github.com/cundong/SmartAppUpdates

这里有一个实验包, 使用它就可以在windows中直接完成拆分
http://download.csdn.net/detail/hmg25/4676737

我今天做个记录吧, 省得以后用到之后又忘了,我水平不行,先会用就行了

实现

首先我下载了SmartAppUpdates项目,项目是使用eclipse编的, 直接运行这个没什么意思,最近一直再用android studio,所以现在studio 上编一下。
jni的代码不是很多,其中用到了一个库叫 bzip2,但是在编译的时候遇到了一个问题, 这里记录一下吧,等之后找一下答案。
我在android studio上搭建了一个ndk项目, 我先试着自己写一个c函数,这个是可以编译过的,也返回了正确的结果,但是例子上的代码(图中)就仅仅是调用了applypatch,在编译的时候android studio提示各种的

                                  multiple definition of `xxxxxx'

我后来又在eclipse下重新编译了项目,是可以生成so文件的,查了一会没有结果也就放弃了,直接就用github上提供so库了, 今天找到了解决问题的方法,写在了文章的最后了

Paste_Image.png

用人家的so库包名就不能改,直接把这个文件放进去就可以了, 在android studio 使用so库有一种简单的办法,就是在项目中的java文件夹的统计目录创建一个jniLibs文件夹, 然后把so放进去就可以了

Paste_Image.png
Paste_Image.png

然后再activity中直接调用就好了

package org.chitarra.tiny.myapplication.view;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import android.support.design.widget.FloatingActionButton;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import android.widget.Toast;
import static com.cundong.utils.PatchUtils.patch;

import org.chitarra.tiny.myapplication.R;

import java.io.File;
public class UpdataActivity extends AppCompatActivity {
    public static final String PATH = Environment.getExternalStorageDirectory() +
        File.separator;

    public static final String NEW_APK_PATH = PATH + "new.apk";

    public static final String PATCH_PATH = PATH + "test.patch";

    static {
        System.loadLibrary("ApkPatchLibrary");
    }

    private FloatingActionButton mBut;
    Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case 0:
                    Toast.makeText(UpdataActivity.this, "OK", Toast.LENGTH_SHORT)
                         .show();
                    installApk();

                    break;

                case -1:
                    Toast.makeText(UpdataActivity.this, "error",
                        Toast.LENGTH_SHORT).show();

                    break;

                default:
                    break;
                }

                super.handleMessage(msg);
            }
        };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_updata);

        this.mBut = (FloatingActionButton) findViewById(R.id.fab);
        this.mBut.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    File patchFile = new File(PATCH_PATH);
                    if (!patchFile.exists()) {
                        Toast.makeText(UpdataActivity.this, "patch not exists",
                            Toast.LENGTH_SHORT).show();
                    } else {
                        new PatchThread().start();
                    }
                }
            });
    }

    private void installApk() {
        File file = new File(NEW_APK_PATH);

        if (file.exists()) {
            Uri uri = Uri.fromFile(file);
            Intent installIntent = new Intent(Intent.ACTION_VIEW);
            installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            installIntent.setDataAndType(uri,
                "application/vnd.android.package-archive");
            this.startActivity(installIntent);
        }
    }

    class PatchThread extends Thread {
        @Override
        public void run() {
            String oldAppPatch = getApplicationContext().getApplicationInfo().sourceDir;

            int patchResult = patch(oldAppPatch, NEW_APK_PATH, PATCH_PATH);

            if (patchResult == 0) {
                mHandler.sendEmptyMessage(0);
            } else {
                mHandler.sendEmptyMessage(-1);
            }
        }
    }
}

代码不是很复杂, 就没写注释了,但是还要记录几点,省得以后忘记
NEW_APK_PATH :是与差分文件合并生成的apk,在指定目录下,就会生成一个new.apk
PATCH_PATH :拆分文件, xxxx.patch的格式的
patch: 这是一个本地方法,其中三个变量都是需要传的,第一个变量可以通过

getApplicationContext().getApplicationInfo().sourceDir;

这种方式得到

最后的最后的最后, 重要的事情说三遍,在AndroidManifest.xml中要加入权限

Paste_Image.png

好了, 基本上能记录的就这么多了, 下面试程序运行时的效果图

Paste_Image.png
Paste_Image.png
Paste_Image.png

这是项目中使用到的全部文件,csdn 上传代码太慢了,传到了百度云上
http://pan.baidu.com/s/1hru9FDU


今天我有重新拿android studio 重新编译了一下以上的代码, 发现昨天的代码中间会有基础错误,今天修正了之后就能编译出so的库了

创建一个android studio jni的项目

在项目中新建一个jni文件夹

Paste_Image.png

这个时候,android studio会自动的在这个项目中的build.gradle生成一个
sourceSets { main { jni.srcDirs = ['src/main/jni'] } }
至于是生成.h 在activity中引入native这些都没有变,紧接着我们就把bzip2的源码拖进来,因为直接在org_chitarra_tiny_jniresr_Patch.c这个文件中引入的是#include "bzlib.c" 这样就会发生很多重复定义的错误

Paste_Image.png

等我把#include "bzlib.c"改成#include "bzlib.h" 错误就不会出现了,程序也会正常的执行了,证明昨天的做法是没有问题的,只是没有改这个

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容