利用bugly热更新和美团walle多渠道打包

2018-03-03 18:09:51

步骤

1.工程目录下

dependencies {
    classpath 'com.android.tools.build:gradle:3.0.0'
    classpath 'com.mob.sdk:MobSDK:+'
    classpath 'com.meituan.android.walle:plugin:1.1.6'

    // tinkersupport插件, 其中lastest.release指拉取最新版本,也可以指定明确版本号,例如1.0.4
    classpath "com.tencent.bugly:tinker-support:1.1.1"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

2.moudle下面

apply plugin: 'com.android.application'
// 依赖插件脚本
apply from: 'tinker-support.gradle'

apply plugin: 'walle'
android {
    compileSdkVersion 26


    defaultConfig {
        applicationId "com.m****u.m****u.m****u"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.1.1"   //别忘了修改热修补的版本号和热修补部署文件  开启think

        renderscriptSupportModeEnabled true  //检查图片合法性
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // dex突破65535的限制
        multiDexEnabled true
/*
        signingConfig signingConfigs.config_debug
*/

        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
    signingConfigs {
        config_debug {
            keyAlias 'mamaxiqu'
            keyPassword '15966247549dD'
            storeFile file('C:/work/liupeng/m****u.jks')
            storePassword 'm****u'
        }
        release {
            keyAlias 'mamaxiqu'
            keyPassword '15966247549dD'
            storeFile file('C:/work/liupeng/m****u.jks')
            storePassword 'm****u'
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            debuggable true
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.release
        }
    }

}
walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

    compile "com.android.support:multidex:1.0.1" // 多dex配置
    //注释掉原有bugly的仓库
    /*bugly*/
    implementation 'com.tencent.bugly:crashreport_upgrade:1.3.4'
    //其中latest.release指代最新版本号,也可以指定明确的版本号,例如1.2.0
    implementation 'com.tencent.bugly:nativecrashreport:3.3.1'
    //其中latest.release指代最新版本号,也可以指定明确的版本号,例如2.2.0

    compile 'com.meituan.android.walle:library:1.1.6'

}


3.创建tinker-support.gradle  注意把加固打开

apply plugin: 'com.tencent.bugly.tinker-support'


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

/**
 * 此处填写每次构建生成的基准包目录
 */
def baseApkDir = "samename-0303-17-14-08"

/**
 * 对于插件各参数的详细解析请参考
 */
tinkerSupport {

    // 开启tinker-support插件,默认值true
    enable = true

    // 指定归档目录,默认值当前module的子目录tinker
    autoBackupApkDir = "${bakPath}"

    // 是否启用覆盖tinkerPatch配置功能,默认值false
    // 开启后tinkerPatch配置不生效,即无需添加tinkerPatch
    overrideTinkerPatchConfiguration = true

    // 编译补丁包时,必需指定基线版本的apk,默认值为空
    // 如果为空,则表示不是进行补丁包的编译
    // @{link tinkerPatch.oldApk }
    baseApk = "${bakPath}/${baseApkDir}/samename-release.apk"

    // 对应tinker插件applyMapping
    baseApkProguardMapping = "${bakPath}/${baseApkDir}/samename-release-mapping.txt"

    // 对应tinker插件applyResourceMapping
    baseApkResourceMapping = "${bakPath}/${baseApkDir}/samename-release-R.txt"

    // 构建基准包和补丁包都要指定不同的tinkerId,并且必须保证唯一性
    //  tinkerId = "1.1.1base"
    tinkerId = "1.1.1-patch"

    // 构建多渠道补丁时使用
    // buildAllFlavorsDir = "${bakPath}/${baseApkDir}"

    // 是否启用加固模式,默认为false.(tinker-spport 1.0.7起支持)
     isProtectedApp = true

    // 是否开启反射Application模式
    enableProxyApplication = true

    // 是否支持新增非export的Activity(注意:设置为true才能修改AndroidManifest文件)
    supportHotplugComponent = true

}

/**
 * 一般来说,我们无需对下面的参数做任何的修改
 * 对于各参数的详细介绍请参考:
 * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
 */
tinkerPatch {
    //oldApk ="${bakPath}/${appName}/app-release.apk"
    ignoreWarning = false
    useSign = true
    dex {
        dexMode = "jar"
        pattern = ["classes*.dex"]
        loader = []
    }
    lib {
        pattern = ["lib/*/*.so"]
    }

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

    packageConfig {
    }
    sevenZip {
        zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
//        path = "/usr/local/bin/7za"
    }
    buildConfig {
        keepDexApply = false
        //tinkerId = "1.0.1-base"
        //applyMapping = "${bakPath}/${appName}/app-release-mapping.txt" //  可选,设置mapping文件,建议保持旧apk的proguard混淆方式
        //applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配
    }
}

4.编写自己的application  并配置

package com.jgl.divination.samename;

import android.app.Application;
import android.content.Context;
import android.support.multidex.MultiDex;

import com.meituan.android.walle.WalleChannelReader;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.BuglyStrategy;
import com.tencent.bugly.beta.Beta;

/**
 * Created by on 2018/2/25 0025.
 */

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        BuglyStrategy strategy1 = new BuglyStrategy();

        String channel = WalleChannelReader.getChannel(getApplicationContext());
        strategy1.setAppChannel(channel);
        Bugly.init(getApplicationContext(),"*******",true,strategy1);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        // you must install multiDex whatever tinker is installed!
        MultiDex.install(base);


        // 安装tinker
        Beta.installTinker();
    }
}

5.进行channel配置

samsungapps #三星
huawei #华为
kuan  #酷安
anzhi  #安智
ali   #阿里分发
xiaomi # 小米
gfan  #机锋   有支付sdk
appchina #应用汇  尚未注册
nduoa  #N多市场   公司用户
3gcn  #3G门户 暂时没用
mumayi  #木蚂蚁
10086com
wostore  #联通
189store
lenovomm
hicloud
meizu
wandou
# Google Play
# googleplay
# 百度
baidu
#
# 360
360cn
#
# 应用宝
myapp


6.AndroidManifest.xml 配置 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.***.****.samename">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


    <application
        android:name=".MyApplication"

        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--bugly 配置-->
        <activity
            android:name="com.tencent.bugly.beta.ui.BetaActivity"
            android:configChanges="keyboardHidden|orientation|screenSize|locale"
            android:theme="@android:style/Theme.Translucent" />

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>

</manifest>



7. 添加xml/provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk-->
    <external-path name="beta_external_path" path="Download/"/>
    <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/-->
    <external-path name="beta_external_files_path" path="Android/data/"/>
</paths>



这就大功完成了



8.多渠道包生成

首先更改tinker-support.gradle配置:(还要更改相应的版本号)

  tinkerId = "1.1.1base"
//tinkerId = "1.1.1-patch"

双击pacage下面的assembleReleaseChannels进行编译,生成文件在channel文件夹下面

这写apk就可以使用了,是带有热更新公共的apk,然后也可以进行加固


9.更新包生成

首先更改tinker-support.gradle配置:(还要更改相应的版本号)

 // tinkerId = "1.1.1base"
tinkerId = "1.1.1-patch"/**
 * 此处填写每次构建生成的基准包目录
 */
def baseApkDir = "samename-0303-17-14-08"


双击thinker-support羡慕的buildThinkerPatchRelease,把生成的patch_signed_7zip.apk上传bugly。

剩下的就交个bugly了。

  • 2019-12-05 17:01:36

    Vue 结合 Axios 接口超时统一处理

    当网路慢的时候。又或者公司服务器不在内地的时候,接口数据请求不回来超时报错的情况相信大家肯定遇到过的,这里我把我公司项目请求超时的处理方法分享下,希望看过后有帮助。

  • 2019-12-05 17:13:40

    JS模板工具lodash.template的简单用法

    lodash是从underscore分支的一个项目,之前我写了一篇JS模板工具underscore.template的简单用法,lodash跟underscore很相似,这也简单介绍一下lodash的template方法。 先把underscore的文章中用过的代码贴过来,把underscore的js文件换成lodash的js,其他一字不改,然后我们试试:

  • 2019-12-06 10:47:29

    date-fns日期工具的使用方法详解

    isToday() 判断传入日期是否为今天 isYesterday() 判断传入日期是否为昨天 isTomorrow() 判断传入日期是否为 format() 日期格式化 addDays() 获得当前日期之后的日期 addHours() 获得当前时间n小时之后的时间点 addMinutes() 获得当前时间n分钟之后的时间 addMonths() 获得当前月之后n个月的月份 subDays() 获得当前时间之前n天的时间 subHours() 获得当前时间之前n小时的时间 subMinutes() 获得当前时间之前n分钟的时间 subMonths() 获得当前时间之前n个月的时间 differenceInYears() 获得两个时间相差的年份 differenceInWeeks() 获得两个时间相差的周数 differenceInDays() 获得两个时间相差的天数 differenceInHours() 获得两个时间相差的小时数 differenceInMinutes() 获得两个时间相差的分钟数

  • 2019-12-06 10:49:39

    npm 查看源 换源

    npm,cnpm,查看源,切换源,npm config set registry https://registry.npmjs.org

  • 2019-12-06 11:01:31

    npm发布包流程详解 有demo

    npm发布包步骤,以及踩过的坑(见红颜色标准): 1.注册npm账号,并完成Email认证(否则最后一步提交会报Email错误) 2.npm添加用户或登陆:npm adduser 或 npm login

  • 2019-12-06 13:16:18

    vue mixins组件复用的几种方式

    最近在做项目的时候,研究了mixins,此功能有妙处。用的时候有这样一个场景,页面的风格不同,但是执行的方法,和需要的数据非常的相似。我们是否要写两种组件呢?还是保留一个并且然后另个一并兼容另一个呢? 不管以上那种方式都不是很合理,因为组件写成2个,不仅麻烦而且维护麻烦;第二种虽然做了兼容但是页面逻辑造成混乱,必然不清晰;有没有好的方法,有那就是用vue的混合插件mixins。混合在Vue是为了提出相似的数据和功能,使代码易懂,简单、清晰。

  • 2019-12-06 13:26:30

    vue的mixins混入合并规则

    混入minxins:分发vue组件中可复用功能的灵活方式。混入对象可以包含任意组件选项。组件使用混入对象时,所有混入对象的选项将混入该组件本身的选项。

  • 2019-12-06 16:50:34

    Intellij idea 如何关闭无用的提示

    Linux:Settings —> Editor —> Inspections —> General —> Duplicated Code Mac:Preferences --> Editor —> Inspections —> General —> Duplicated Code fragment 将对应的勾去掉。