Android之Tinker使用

1.导入依赖

    //可选,用于生成application类
    provided('com.tencent.tinker:tinker-android-anno:1.9.2')
    //tinker的核心库
    compile('com.tencent.tinker:tinker-android-lib:1.9.2')
    //分包
    compile 'com.android.support:multidex:1.0.1'
----------------------------------------------------------------------------
1.1在AndroidManifast中配置:

    <application>
        <meta-data android:name="TINKER_ID" android:value="tinker_id_b168b32"/>
    </application>
----------------------------------------------------------------------------
2.创建Application继承DefaultApplicationLike
public class CustomApplication extends DefaultApplicationLike{

    public CustomApplication(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
    }

    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
    //开启分包
        MultiDex.install(base);
        //安装
        TinkerManager.installTinbker(this);

    }
}
----------------------------------------------------------------------------

3.创建类TinkerManager
public class TinkerManager {

    //是否安装
    private static boolean isInstalled = false;
    private static ApplicationLike app;

    /**
     * 安装
     */
    public static void installTinbker(ApplicationLike applicationLike){
        app=applicationLike;
        //判断是否安装
        if(isInstalled){
            return;
        }
        TinkerInstaller.install(applicationLike);
        isInstalled=true;
    }

    /**
     * 添加补丁包
     * @param path
     */
    public static void addPatch(String path){
        if(isInstalled){
            TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(),path);
        }
    }

    /**
     * 从ApplicationLike中拿到上下文
     */
    public static Context getApplicationContext(){
        return app.getApplication().getApplicationContext();
    }

}
----------------------------------------------------------------------------
4.给Application类添加注解(第2步的类上添加此注解)
    @DefaultLifeCycle(
        application = ".MyTinkerApplication",             //application name to generate 应用程序名称生成
        flags = ShareConstants.TINKER_ENABLE_ALL)         //tinkerFlags above tinkerFlags上面

4.1 编译一下生成一个.MyTinkerApplication  在清单文件中注册
----------------------------------------------------------------------------
5.在SD卡下生成一个文件夹   (路径名 /storage/emulated/0/tpatch/)  //将生成的补丁包放入此文件夹下

                                  //后缀
    private static final  String SUFFIX=".apk";
    private String patchPath="";

    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
            patchPath=absolutePath.concat(File.separator).concat("tpatch/");
            File file = new File(patchPath);
            Log.e(TAG, "onCreate: 路径名 "+patchPath);
            if(!file.exists()){
                file.mkdir();
            }
        }

   /**
     * 返回补丁路径
     * @return
     */
    private String getPatchPath(){
        return patchPath.concat("out").concat(SUFFIX);
    }

点击调用方法:     TinkerManager.addPatch(getPatchPath());   //添加补丁包

----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------

*  gradle接入  *
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
//在Project下build.gradle中配置
dependencies {
        classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.2')
    }

//apply tinker插件  (在model的 build.gradle第二行配置)
apply plugin: 'com.tencent.tinker.patch'
----------------------------------------------------------------------------
22222222222222222222222222222222222222222222222222222222222222222222222222222222222
(在model的 build.gradle配置最下面)
在build下创建一个bakApk文件夹

def bakPath = file("${buildDir}/bakApk/")

ext{
    tinkerOldApkPath = "${bakPath}/"
    tinkerEnabled = true;
    //不开启混淆
    //tinkerApplyMappingPath = "${bakPath}/"
    tinkerApplyResourcePath = "${bakPath}/"
    //多渠道打包
    //tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}

def getOldApkPath() {
    return ext.tinkerOldApkPath
}
//是否使用Tinker
def buildWithTinker() {
    return ext.tinkerEnabled
}

def getApplyMappingPath() {
    return ext.tinkerApplyMappingPath
}

def getApplyResourceMappingPath() {
    return ext.tinkerApplyResourcePath
}

def getTinkerIdValue() {
    return "tinker_id_b168b32"
}
//多渠道打包
/*def getTinkerBuildFlavorDirectory() {
    return ext.tinkerBuildFlavorDirectory
}*/

tinkerPatch{
    tinkerEnable = buildWithTinker()
    oldApk = getOldApkPath()
    ignoreWarning = false
    useSign = true

    buildConfig{
        //不开启混淆不用他
        //applyMapping = getApplyMappingPath()
        applyResourceMapping = getApplyResourceMappingPath()
        tinkerId = getTinkerIdValue()
        keepDexApply = false                //分包 暂时不用 太小
        isProtectedApp = false              //加固  暂时不加
    }

    dex{
        dexMode = "jar"
        pattern = ["classes*.dex",
                "assets/secondary-dex-?.jar"]
        //全路径Application
        loader = ["com.geekghost.gp.tinker.MyTinkerApplication"]
    }

    lib{
        pattern = ["lib/*/*.so"]
    }

    res{
        pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
        ignoreChange = ["assets/sample_meta.txt"]
        largeModSize = 100
    }

    packageConfig{
        configField ("version_name","1")
        configField ("change_log","添加了一些新功能")
    }

}
----------------------------------------------------------------------------
333333333333333333333333333333333333333333333333333333333333333333333333333
配置完成后打开右侧的Gradle,找到Tasks\build\assembleRelease双击编译一个Release的apk包
在项目的outputs\apk下

也可以在Terminal(命令行)输入 gradle assembleRelease    代替双击操作

----------------------------------------------------------------------------
444444444444444444444444444444444444444444444444444444444444444444444444444
此脚本在最下面复制 比较固定 用于生产老的apk文件

List<String> flavors = new ArrayList<>();
project.android.productFlavors.each { flavor ->
    flavors.add(flavor.name)
}
boolean hasFlavors = flavors.size() > 0
def date = new Date().format("MMdd-HH-mm-ss")

/**
 * bak apk and mapping
 */
android.applicationVariants.all { variant ->
    /**
     * task type, you want to bak
     */
    def taskName = variant.name

    tasks.all {
        if ("assemble${taskName.capitalize()}".equalsIgnoreCase(it.name)) {

            it.doLast {
                copy {
                    def fileNamePrefix = "${project.name}-${variant.baseName}"
                    def newFileNamePrefix = hasFlavors ? "${fileNamePrefix}" : "${fileNamePrefix}-${date}"

                    def destPath = hasFlavors ? file("${bakPath}/${project.name}-${date}/${variant.flavorName}") : bakPath
                    from variant.outputs.first().outputFile
                    into destPath
                    rename { String fileName ->
                        fileName.replace("${fileNamePrefix}.apk", "${newFileNamePrefix}.apk")
                    }

                    from "${buildDir}/outputs/mapping/${variant.dirName}/mapping.txt"
                    into destPath
                    rename { String fileName ->
                        fileName.replace("mapping.txt", "${newFileNamePrefix}-mapping.txt")
                    }

                    from "${buildDir}/intermediates/symbols/${variant.dirName}/R.txt"
                    into destPath
                    rename { String fileName ->
                        fileName.replace("R.txt", "${newFileNamePrefix}-R.txt")
                    }
                }
            }
        }
    }
}

----------------------------------------------------------------------------
55555555555555555555555555555555555555555555555555555555555555555555555555555

配置一个正式的签名文件 (可以快捷生产)

android {
    signingConfigs {
        release {
            keyAlias 'key0'
            keyPassword '123456'
            storeFile file('C:/Users/ZangH/Desktop/Tinker/tk.jks')
            storePassword '123456'
        }
    }
}

----------------------------------------------------------------------------
6666666666666666666666666666666666666666666666666666666666666666666666666666
重复3333333333333
这次生成后会在bakApk下生成一个备份的的apk和R文件

----------------------------------------------------------------------------
777777777777777777777777777777777777777777777777777777777777777777777777777

把bakApk的老的apk的名字copy下来把   tinkerOldApkPath = "${bakPath}/" 填好
把bakApk的老的R文件的名字copy下来把tinkerApplyResourcePath = "${bakPath}/" 填好

如下:

ext{
    tinkerOldApkPath = "${bakPath}/tinker-release-0118-11-10-48.apk"
    tinkerApplyResourcePath = "${bakPath}/tinker-release-0118-11-10-48-R.txt"
}

----------------------------------------------------------------------------
8888888888888888888888888888888888888888888888888888888888888888888888888888

上一步配置完成后点击打开右侧的Gradle,找到Tasks\tinker\tinkerPatchRelease双击编译一个新的包在
备份包里有新的R文件和apk,同时在build\output里的tinkerPatch里生成补丁apk(patch_signed.apk)

接下来只需把补丁包放入我们定义的修改路径就好了


然后每次更新补丁包生成新的apk后吧上一个备份好的apk和R文件路径修改即可:(具体看第7步)







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值