您的位置:首页 > 移动开发 > 微信开发

微信热修复框架Tinker的使用

2016-10-28 12:58 423 查看
1、在project目录下的build.gradle的dependencies下添加如下代码:

classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.1')


2、添加依赖配置到你的app/build.gradle的dependencies下:

provided('com.tencent.tinker:tinker-android-anno:1.7.1')
compile('com.tencent.tinker:tinker-android-lib:1.7.1')


3、在app/build.gradle的dependencies的最外层添加下面这些配置:

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

ext {

tinkerEnabled = true

//for normal build
//原来的apk地址
tinkerOldApkPath = "${bakPath}/app-debug-1028-12-47-25.apk"

//如果资源文件改变了,这项必须填写
//tinkerApplyResourcePath = "${bakPath}/app-debug-1018-17-32-47-R.txt"

//只用于多渠道打包,没有的可以忽略
//tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}

def getOldApkPath() {
return hasProperty("OLD_APK") ? OLD_APK : ext.tinkerOldApkPath
}

/*def getApplyMappingPath() {
return hasProperty("APPLY_MAPPING") ? APPLY_MAPPING : ext.tinkerApplyMappingPath
}*/

/*def getApplyResourceMappingPath() {
return hasProperty("APPLY_RESOURCE") ? APPLY_RESOURCE : ext.tinkerApplyResourcePath
}*/
//TINKER_ID可以自己指定
def getTinkerIdValue() {
return hasProperty("TINKER_ID") ? TINKER_ID : "100"
}

def buildWithTinker() {
return hasProperty("TINKER_ENABLE") ? TINKER_ENABLE : ext.tinkerEnabled
}

/*def getTinkerBuildFlavorDirectory() {
return ext.tinkerBuildFlavorDirectory
}*/

if (buildWithTinker()) {
apply plugin: 'com.tencent.tinker.patch'

tinkerPatch {
//必须的
oldApk = getOldApkPath()
//可选的,默认为false
ignoreWarning = false

//可选,默认为true
useSign = true

buildConfig {

//可选的,由于这用不到所以注释掉了
//            applyMapping = getApplyMappingPath()
//可选
//            applyResourceMapping = getApplyResourceMappingPath()

//必须的
tinkerId = getTinkerIdValue()
}

dex {
//可选,默为jar
dexMode = "jar"
//可选,默认为false
usePreGeneratedPatchDex = false
//必须的,默认为[]
pattern = ["classes*.dex",
"assets/secondary-dex-?.jar"]
//必须的,默认为[]
loader = ["com.tencent.tinker.loader.*",
//这里必须换成你自己的Application
"tinker.sample.android.app.SampleApplication"]
}

lib {
//可选,默认为[]
pattern = ["lib/armeabi/*.so"]
}

res {
//可选,默认为[]
pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]

//可选,默认为[]
ignoreChange = ["assets/sample_meta.txt"]

//默认为100kb
largeModSize = 100
}

packageConfig {
//可选
configField("patchMessage", "tinker is sample to use")

}

/**
* if you don't use zipArtifact or path, we just use 7za to try
*/
sevenZip {

//可选,默认为7zip
zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
/**
* optional,default '7za'
* you can specify the 7za path yourself, it will overwrite the zipArtifact value
*/
//        path = "/usr/local/bin/7za"
}
}

/**
* 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 date = new Date().format("MMdd-HH-mm-ss")
from "${buildDir}/outputs/apk/${project.getName()}-${taskName}.apk"
into bakPath
rename { String fileName ->
fileName.replace("${project.getName()}-${taskName}.apk", "${project.getName()}-${taskName}-${date}.apk")
}

from "${buildDir}/outputs/mapping/${taskName}/mapping.txt"
into bakPath
rename { String fileName ->
fileName.replace("mapping.txt", "${project.getName()}-${taskName}-${date}-mapping.txt")
}

from "${buildDir}/intermediates/symbols/${taskName}/R.txt"
into bakPath
rename { String fileName ->
fileName.replace("R.txt", "${project.getName()}-${taskName}-${date}-R.txt")
}
}
}
}
}
}

}


4、自定义applicaiton继承DefaultApplicationLike,并且添加注解@DefaultLifeCycle,如果你之前的代码已经有自定义的application,可以将你的application继承DefaultApplicationLike,而不是Applicaiton。

@DefaultLifeCycle(application = "com.ress.tinker.app.SampleApplicaiton",
flags = ShareConstants.TINKER_ENABLE_ALL)
public class MyApplication extends DefaultApplicationLike {

public MyApplication(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) {
super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent, resources, classLoader, assetManager);
}


application=“com.ress.tinker.app.SampleApplication"中的类名可以自己定义,这个类将由TInker自动生成。并在AndroidManifest,xml文件的applicaiton标签中声明。

<application
android:name=".app.SampleApplicaiton"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">


5、重写MyApplicaiton的OnBaseContextAttached()方法,并初始化TInker

@DefaultLifeCycle(application = "com.ress.tinker.app.SampleApplicaiton",
flags = ShareConstants.TINKER_ENABLE_ALL)
public class MyApplication extends DefaultApplicationLike {

public MyApplication(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) {
super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent, resources, classLoader, assetManager);
}

@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
TinkerInstaller.install(this);
}
}


6、加载修复代码

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TinkerInstaller.onReceiveUpgradePatch(MainActivity.this, Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");

Toast.makeText(this, "有Bug!!", Toast.LENGTH_SHORT).show();
}
}

Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk"
这是修复后的apk放在手机中的位置

6、打开android studio右侧的gradle面板,找到assembleDebug,双击



7、打开build/bakapk,将apk装到手机里



将apk名字复制到之前app/build.gradle中的tinkerOldApk处

ext {
//for some reason, you may want to ignore tinkerBuild, such as instant run debug build?
tinkerEnabled = true

//for normal build
//原来的apk地址
<span style="color:#ff6666;">tinkerOldApkPath = "${bakPath}/app-debug-1028-12-47-25.apk"</span>

//如果资源文件改变了,这项必须填写
//tinkerApplyResourcePath = "${bakPath}/app-debug-1018-17-32-47-R.txt"

//只用于多渠道打包,没有的可以忽略
//tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}


8、修改土司的内容,再次打开android studio右侧的gradle面板,双击tinker/tinkerPatchDebug



9、在build/outputs/tinkerpatch下找到patch_signed_7zip.apk,并拷贝到手机内存根目录



注意:

不能忘记权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
10、运行之前的apk,干掉进程之后再次打开,会发现土司的内容变了。

最后感谢简书红飞大神的基于腾讯Tinker热修复框架的Demo和腾讯的Tinker,才能顺利的集成Tinker。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息