• 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中直接调用就好了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    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() +
    大专栏  Android 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: 这是一个本地方法,其中三个变量都是需要传的,第一个变量可以通过

    1
    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” 错误就不会出现了,程序也会正常的执行了,证明昨天的做法是没有问题的,只是没有改这个

  • 相关阅读:
    SSH隧道,解决MySQL访问时,报Access denied for user 'xxx'@'localhost'的错误
    Linux(debianxfce) 输入法
    getopt函数
    【分布式事务】
    记录chrome中cookies设置的一个问题
    antdv 表格table中customRender
    OAuth2.0及token刷新流程
    笔记草稿
    Openvas QoD 说明
    elementaryos6.1stable.20211218rc.iso 下载磁链
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12251510.html
Copyright © 2020-2023  润新知