Android热更新框架Tinker探索之旅.docx

上传人:b****7 文档编号:9694169 上传时间:2023-02-05 格式:DOCX 页数:42 大小:179.33KB
下载 相关 举报
Android热更新框架Tinker探索之旅.docx_第1页
第1页 / 共42页
Android热更新框架Tinker探索之旅.docx_第2页
第2页 / 共42页
Android热更新框架Tinker探索之旅.docx_第3页
第3页 / 共42页
Android热更新框架Tinker探索之旅.docx_第4页
第4页 / 共42页
Android热更新框架Tinker探索之旅.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

Android热更新框架Tinker探索之旅.docx

《Android热更新框架Tinker探索之旅.docx》由会员分享,可在线阅读,更多相关《Android热更新框架Tinker探索之旅.docx(42页珍藏版)》请在冰豆网上搜索。

Android热更新框架Tinker探索之旅.docx

Android热更新框架Tinker探索之旅

Android热更新框架Tinker探索之旅

现在比较流行的热修复框架的优缺点和特色,在Tinker的wiki下都可以看到,这里就不在赘述了,Tinker只用了这句话来展现自己的优势:

Tinker已运行在微信的数亿Android设备上,那么为什么你不使用Tinker呢?

Tinker分为gradle接入和命令行接入,但是我这种菜鸟玩不转命令行,所以只能照搬gradle接入Tinker了。

但是我感觉,命令行算不上一种接入,仅仅是多了一种编译差分包的方式而已,当然,这仅仅是个人见解哈,至于我为什么这么说,大家往下看就知道了。

首先,在project的build.gradle文件里需要添加Tinker的插件依赖

dependencies{

classpath'com.android.tools.build:

gradle:

1.3.0'

...

//Tinker

classpath"com.tencent.tinker:

tinker-patch-gradle-plugin:

1.7.7"

}

其次就是主module的build.gradle文件的配置,主要有下面几个地方

1.引入Tinker依赖

dependencies{

//tinker必须要引入多dex打包支持

compile'com.android.support:

multidex:

1.0.1'

//可选,用于注解生成application类

provided("com.tencent.tinker:

tinker-android-anno:

1.7.7"

//tinker依赖版本

compile("com.tencent.tinker:

tinker-android-lib:

1.7.7")

}

2.tinker的一些配置

//-------------------------tinkerconfigstart-------------------------

buildConfigField"String","TINKER_VERSION","\"1.7.7\""

/**

*buildConfigcanchangeduringpatch!

*wecanusethenewlyvaluewhenpatch

*/

buildConfigField"String","MESSAGE","\"Iamthebaseapk\""

/**

*clientversionwouldupdatewithpatch

*sowecangetthenewlygitversioneasily!

*/

buildConfigField"String","TINKER_ID","\"${getTinkerIdValue()}\""

buildConfigField"String","PLATFORM","\"all\""

//-------------------------tinkerconfigend-------------------------

3.编译差分包的开关和老版本文件位置确定

defbakPath=file("${buildDir}/bakApk/")

/**

*youcanuseassembleReleasetobuildyoubaseapk

*usetinkerPatchRelease-POLD_APK=-PAPPLY_MAPPING=-PAPPLY_RESOURCE=tobuildpatch

*addapkfromthebuild/bakApk

*/

ext{

defoldPrefixFormat="app_beta1_${appVersionName}_${newDate().format("yyyy_MM_dd")}_%s_build${appVersionCode}_%s"

defoldApkPath=String.format(oldPrefixFormat,"10_34_38","tinker.apk")

defapplyMappingPath=String.format(oldPrefixFormat,"10_34_38","mapping.txt")

defresourcePath=String.format(oldPrefixFormat,"10_34_38","R.txt")

//forsomereason,youmaywanttoignoretinkerBuild,suchasinstantrundebugbuild?

tinkerEnabled=true

//fornormalbuild

//oldapkfiletobuildpatchapk

tinkerOldApkPath="${bakPath}/${oldApkPath}"

//proguardmappingfiletobuildpatchapk

tinkerApplyMappingPath="${bakPath}/${applyMappingPath}"

//resourceR.txttobuildpatchapk,mustinputifthereisresourcechanged

tinkerApplyResourcePath="${bakPath}/${resourcePath}"

//onlyuseforbuildallflavor,ifnot,justignorethisfield

tinkerBuildFlavorDirectory="${bakPath}/app-patch-${releaseTime()}"

}

4.tinker编译差分包的task配置

tinkerPatch{

/**

*necessary,default'null'

*theoldapkpath,usetodiffwiththenewapktobuild

*addapkfromthebuild/bakApk

*/

oldApk=getOldApkPath()

/**

*optional,default'false'

*therearesomecaseswemaygetsomewarnings

*ifignoreWarningistrue,wewouldjustassertthepatchprocess

*case1:

minSdkVersionisbelow14,butyouareusingdexModewithraw.

*itmustbecrashwhenload.

*case2:

newlyaddedAndroidComponentinAndroidManifest.xml,

*itmustbecrashwhenload.

*case3:

loaderclassesindex.loader{}arenotkeepinthemaindex,

*itmustbelettinkernotwork.

*case4:

loaderclassesindex.loader{}changes,

*loaderclassesisuestoloadpatchdex.itisuselesstochangethem.

*itwon'tcrash,butthesechangescan'teffect.youmayignoreit

*case5:

resources.arschaschanged,butwedon'tuseapplyResourceMappingtobuild

*/

ignoreWarning=false

/**

*optional,default'true'

*whethersignthepatchfile

*ifnot,youmustdoyourself.otherwiseitcan'tchecksuccessduringthepatchloading

*wewillusethesignconfigwithyourbuildtype

*/

useSign=true

/**

*optional,default'true'

*whetherusetinkertobuild

*/

tinkerEnable=buildWithTinker()

/**

*Warning,applyMappingwillaffectthenormalandroidbuild!

*/

buildConfig{

/**

*optional,default'null'

*ifweusetinkerPatchtobuildthepatchapk,you'dbettertoapplytheold

*apkmappingfileifminifyEnabledisenable!

*Warning:

*youmustbecarefulthatitwillaffectthenormalassemblebuild!

*/

applyMapping=getApplyMappingPath()

/**

*optional,default'null'

*ItisnicetokeeptheresourceidfromR.txtfiletoreducejavachanges

*/

applyResourceMapping=getApplyResourceMappingPath()

/**

*necessary,default'null'

*becausewedon'twanttocheckthebaseapkwithmd5intheruntime(itisslow)

*tinkerIdisusetoidentifytheuniquebaseapkwhenthepatchistriedtoapply.

*wecanusegitrev,svnrevorsimplyversionCode.

*wewillgenthetinkerIdinyourmanifestautomatic

*/

tinkerId=getTinkerIdValue()

/**

*ifkeepDexApplyistrue,classinwhichdexrefertotheoldapk.

*openthiscanreducethedexdifffilesize.

*/

keepDexApply=false

}

dex{

/**

*optional,default'jar'

*onlycanbe'raw'or'jar'.forraw,wewouldkeepitsoriginalformat

*forjar,wewouldrepackdexeswithzipformat.

*ifyouwanttosupportbelow14,youmustusejar

*oryouwanttosaveromorcheckquicker,youcanuserawmodealso

*/

dexMode="jar"

/**

*necessary,default'[]'

*whatdexesinapkareexpectedtodealwithtinkerPatch

*itsupport*or?

pattern.

*/

pattern=["classes*.dex",

"assets/secondary-dex-?

.jar"]

/**

*necessary,default'[]'

*Warning,itisveryveryimportant,loaderclassescan'tchangewithpatch.

*thus,theywillberemovedfrompatchdexes.

*youmustputthefollowingclassintomaindex.

*Simply,youshouldaddyourownapplication{@codetinker.sample.android.SampleApplication}

*owntinkerLoader,andtheclassesyouuseinthem

*

*/

loader=[

//usesample,letBaseBuildInfounchangeablewithtinker

"com.simpletour.client.tinker.app.BaseBuildInfo"

]

}

lib{

/**

*optional,default'[]'

*whatlibraryinapkareexpectedtodealwithtinkerPatch

*itsupport*or?

pattern.

*forlibraryinassets,wewouldjustrecovertheminthepatchdirectory

*youcangettheminTinkerLoadResultwithTinker

*/

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

}

res{

/**

*optional,default'[]'

*whatresourceinapkareexpectedtodealwithtinkerPatch

*itsupport*or?

pattern.

*youmustincludeallyourresourcesinapkhere,

*otherwise,theywon'trepackinthenewapkresources.

*/

pattern=["res/*","assets/*","resources.arsc","AndroidManifest.xml"]

/**

*optional,default'[]'

*theresourcefileexcludepatterns,ignoreadd,deleteormodifyresourcechange

*itsupport*or?

pattern.

*Warning,wecanonlyuseforfilesnorelativewithresources.arsc

*/

ignoreChange=["assets/sample_meta.txt"]

/**

*default100kb

*formodifyresource,ifitislargerthan'largeModSize'

*wewouldliketousebsdiffalgorithmtoreducepatchfilesize

*/

largeModSize=100

}

packageConfig{

/**

*optional,default'TINKER_ID,TINKER_ID_VALUE''NEW_TINKER_ID,NEW_TINKER_ID_VALUE'

*packagemetafilegen.pathisassets/package_meta.txtinpatchfile

*youcanusesecurityCheck.getPackageProperties()inyourownPackageCheckmethod

*orTinkerLoadResult.getPackageConfigByName

*wewillgettheTINKER_IDfromtheoldapkmanifestforyouautomatic,

*otherconfigfiles(suchaspatchMessagebelow)isnotnecessary

*/

configField("patchMessage","tinkerissampletouse")

/**

*justasamplecase,youcanusesuchassdkVersion,brand,channel...

*youcanparseitintheSamplePatchListener.

*Thenyoucanusepatchconditional!

*/

configField("platform","all")

/**

*patchversionviapackageConfig

*/

configField("patchVersion","1.0")

}

//oryoucanaddconfigfiledoutside,orgetmetavaluefromoldapk

//project.tinkerPatch.packageConfig.configField("test1",project.tinkerPatch.packageConfig.getMetaDataFromOldApk("Test"))

//project.tinkerPatch.packageConfig.configField("test2","sample")

/**

*ifyoudon'tusezipArtifactorpath,wejustuse7zatotry

*/

sevenZip{

/**

*optional,default'7za'

*the7zipartifactpath,itwillusetheright7zawithyourplatform

*/

zipArtifact="com.tencent.mm:

SevenZip:

1.1.10"

/**

*optional,default'7za'

*youcanspecifythe7zapathyourself,itwilloverwritethezipArtifactvalue

*/

//path="/usr/local/bin/7za"

}

}

5.拷贝和自定义apk、mapping、R文件的别名

/**

*bakapkandmapping

*/

android.applicationVariants.all{variant->

/**

*tasktype,youwanttobak

*/

deftaskName=variant.name

defdate=newDate().format("yyyy_MM_dd_HH_mm_ss")

defbuildTypeName=variant.baseName+""

defisRelease=buildTypeName=="release"

tasks.all{

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

it.doLast{

copy{

//正常情况下生成的apk文件的文件名前缀

deffileNamePrefix="${project.name}-${buildTypeName}"

//自定义apk文件的别名

defnewFileNamePrefix="app_beta1_${isRelease?

"${buildTypeName}_":

""}${appVersionName}_${date}_build${appVersionCode}"

//自定义apk、mapping、R文件存放的目录

defdestPath=hasFlavors?

file("${bakPath}/${project.name}-${date}/${variant.flavorName}"):

bakPath

//复制apk文件和重命名

fromvariant.outputs.outputFile

intodestPath

rename{StringfileName->

fileName.replace("${fileNamePrefix}.apk","${newFileNamePrefix}_tinker.apk")

}

//复制和重命名mapping文件

from"${buildDir}/outputs/mapping/${variant.dirName}/mapping.txt"

intodestPath

rename{StringfileName->

fileName.replace("mapping.txt","${newFileNamePrefix}_mapping.txt")

}

//复制和重命名R文件

from"${buildDir}/intermediates/symbols/${variant.dirName}/R.txt"

intodestPath

rename{StringfileName->

fileName.replace("R.txt","${newFileNamePrefix}_R.txt")

}

}

}

}

}

}

有了上面这些基本的配置,基本上tinker的引入就算完成了。

这里要说一下引入multidex的目的不仅是解决65536的限制,还有就是因为tinker的修复原理是de

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 电大

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1