android Tinker热更新的使用及demo

demo下载地址

https://download.csdn.net/download/u010672559/10551901

一、概述

项目上线之后,经常会临时被告知某个小功能需要被修改,或者说上线了之后才发现某个bug需要紧急修复,于是总能匆匆忙改了段代码又得上线新的版本,极其麻烦,Tinker 是是微信官方的 Android 热修复解决方案,能让用户在没有察觉,没有更新app的情况下实现修复。

二、环境配置

说明:调试时发现麻烦的是配置gradle文件,需要保证没错,其他的注意步骤别搞错了,一步步的来,手机高于6.0的注意需要动态申请权限,demo是在4.4的机器调的,所以没加动态申请权限

1.ProjectName\build.gradle
dependencies {
    classpath 'com.android.tools.build:gradle:3.1.2'
    classpath "com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
2.ProjectName\gradle.properties
添加TINKER_VERSION=1.9.6
3.ProjectName\app\build.gradle配置见具体文件,实际可复制粘贴过去,然后修改applicationId即可,即工程的包名,然后注意导包的不同
4.清单中加权限,application,service定义,其中SampleApplication为打包的时候自动生成的
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
    android:name=".app.SampleApplication"

<service
    android:name=".service.SampleResultService"
    android:exported="false"/>
5.添加SampleApplicationLike和SampleResultService文件,文件名其实可以修改,但是注意清单中做相应更改,
@SuppressWarnings("unused")
@DefaultLifeCycle(application = "com.example.wzhang.tinkertest0719b.SampleApplication",------修改为实际项目的名称
                  flags = ShareConstants.TINKER_ENABLE_ALL,
                  loadVerifyFlag = false)
6..代码调用时如果loadpath出错,可能是没有加动态申请权限的代码,注意机器的Android版本
  public static final int REQUEST_CODE = 0;
    private void checkAndRequestPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            ArrayList<String> permissions = new ArrayList<String>();
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
                Log.i(TAG, "检测无READ_EXTERNAL_STORAGE权限");
            }
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                Log.i(TAG, "检测无WRITE_EXTERNAL_STORAGE权限");
            }
            if(permissions.size()>0){
                //            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
                Log.i(TAG, "请求权限");
                ActivityCompat.requestPermissions(this, permissions.toArray(new String[permissions.size()]), REQUEST_CODE);
                //弹出对话框,注意请求码和之前的检测权限字符想对应
//            }
            }
        }
    }
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    Log.i(TAG, "onRequestPermissionsResult-requestCode="+requestCode);
    switch (requestCode) {
        case REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            for(int i=0;i<permissions.length;i++){
                Log.i(TAG, "i="+i+",permissions[i]="+permissions[i]);
            }
        }
    }
}
7.实际loadpath逻辑如下,可能需要根据实际项目做修改,一般是将文件给服务器,然后现在服务器文件,然后再更新
调试时是将apk文件push到sd卡根目录,且与代码需一致
storage/emulated/0
btnLoad.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Log.d(TAG, "load");
        TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");
    }
});
btnKill.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Log.d(TAG, "kill");
        ShareTinkerInternals.killAllOtherProcess(getApplicationContext());
        android.os.Process.killProcess(android.os.Process.myPid());
    }
});
-------
public void onPatchResult(final PatchResult result) {
        返回是否加载成功的逻辑
}
三、相关文件

ProjectName\app\build.gradle-实际可以复制粘贴意思全部内容,然后修改applicationId即可,同时注意修改对应的complile依赖

apply plugin: 'com.android.application'

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }
    provided("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:multidex:1.0.1'
    testCompile 'junit:junit:4.12'
    //use to test multiDex
    //    compile group: 'com.google.guava', name: 'guava', version: '19.0'
    //    compile "org.scala-lang:scala-library:2.11.7"
}

def gitSha() {
    try {
        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()
        if (gitRev == null) {
            throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
        }
        return gitRev
    } catch (Exception e) {
        throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
    }
}

def javaVersion = JavaVersion.VERSION_1_7

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    compileOptions {
        sourceCompatibility javaVersion
        targetCompatibility javaVersion
    }
    //recommend
    dexOptions {
        jumboMode = true
    }

    signingConfigs {
        release {
            try {
                //官方的demo里面是用的keystore
//                storeFile file("./keystore/release.keystore")
//                storePassword "testres"
//                keyAlias "testres"

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值