From 3fdaeadd19c890bae9478e11bcd51459612b17f4 Mon Sep 17 00:00:00 2001 From: shwenzhang Date: Thu, 5 Jan 2017 21:04:43 +0800 Subject: [PATCH] 1. move TinkerApplication get* method to ApplicationLIke 2. add pmd and findbug check 3. wait dexOpt file generate when patching 4. add TInkerLoadLibrary file to load patch library easier 5. reformat code --- build.gradle | 15 -- findbugs-exclude.xml | 9 + gradle.properties | 2 +- gradle/android-artifacts.gradle | 4 +- gradle/check.gradle | 72 ++++++ gradle/gradle-mvn-push.gradle | 6 +- gradle/java-artifacts.gradle | 3 +- pmd-ruleset.xml | 44 ++++ .../tinker/lib/library/TinkerLoadLibrary.java | 237 ++++++++++++++++++ .../lib/patch/DexDiffPatchInternal.java | 100 +++++--- .../tinker/lib/patch/UpgradePatch.java | 6 + .../lib/service/AbstractResultService.java | 12 +- .../tinker/lib/tinker/TinkerInstaller.java | 92 ------- .../tinker/lib/tinker/TinkerLoadResult.java | 7 +- .../tinker/loader/AndroidNClassLoader.java | 4 + .../tinker/loader/SystemClassLoaderAdder.java | 2 +- .../tencent/tinker/loader/TinkerLoader.java | 1 + .../tinker/loader/app/ApplicationLike.java | 39 ++- .../loader/app/DefaultApplicationLike.java | 7 +- .../tinker/loader/app/TinkerApplication.java | 109 ++++---- .../loader/shareutil/ShareIntentUtil.java | 2 + .../build/gradle/TinkerPatchPlugin.groovy | 4 - .../gradle/task/TinkerPatchSchemaTask.groovy | 12 +- .../tinker/build/decoder/DexDiffDecoder.java | 2 +- .../tencent/tinker/build/info/PatchInfo.java | 3 - .../sample/android/app/MainActivity.java | 1 + .../android/app/SampleApplicationLike.java | 7 +- tinker-sample-android/gradle.properties | 2 +- 28 files changed, 536 insertions(+), 268 deletions(-) create mode 100644 findbugs-exclude.xml create mode 100644 gradle/check.gradle create mode 100644 pmd-ruleset.xml create mode 100644 tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/library/TinkerLoadLibrary.java diff --git a/build.gradle b/build.gradle index 143ac207..41297d17 100644 --- a/build.gradle +++ b/build.gradle @@ -21,21 +21,6 @@ allprojects { enabled = false options.setEncoding('UTF-8') } - - apply plugin: 'checkstyle' - - checkstyle { - configFile rootProject.file('checkstyle.xml') - toolVersion '6.19' - ignoreFailures false - showViolations true - } - - task('checkstyle', type: Checkstyle) { - source 'src/main/java' - include '**/*.java' - classpath = files() - } } ext { diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml new file mode 100644 index 00000000..e3c7c348 --- /dev/null +++ b/findbugs-exclude.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 5dbcb90b..2691a69d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,5 +16,5 @@ # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -VERSION_NAME_PREFIX=1.7.6 +VERSION_NAME_PREFIX=1.7.7 VERSION_NAME_SUFFIX= \ No newline at end of file diff --git a/gradle/android-artifacts.gradle b/gradle/android-artifacts.gradle index 1d14ded6..cd4ded81 100644 --- a/gradle/android-artifacts.gradle +++ b/gradle/android-artifacts.gradle @@ -90,5 +90,5 @@ publishing { task buildAndPublishTinkerToLocalMaven(dependsOn: ['build', 'publishTinkerPatchPublicationToMavenLocal']) { group = 'tinker' } -//depend checkstyle -project.tasks.getByName("check").dependsOn tasks.getByName("checkstyle") + +apply from: rootProject.file('gradle/check.gradle') \ No newline at end of file diff --git a/gradle/check.gradle b/gradle/check.gradle new file mode 100644 index 00000000..739643cd --- /dev/null +++ b/gradle/check.gradle @@ -0,0 +1,72 @@ +apply plugin: 'checkstyle' + + +checkstyle { + configFile rootProject.file('checkstyle.xml') + toolVersion '6.19' + ignoreFailures false + showViolations true +} + +task('checkstyle', type: Checkstyle) { + source 'src/main/java' + include '**/*.java' + classpath = files() +} + +check.dependsOn('checkstyle') + + +apply plugin: 'pmd' +apply plugin: 'findbugs' + +pmd { + toolVersion '5.4.0' +} + +task pmd(type: Pmd) { + targetJdk = TargetJdk.VERSION_1_7 + + description 'Run pmd' + group 'verification' + + // If ruleSets is not empty, it seems to contain some + // defaults which override rules in the ruleset file... + ruleSets = [] + ruleSetFiles = rootProject.files('pmd-ruleset.xml') + source = fileTree('src/main/java') + ignoreFailures = false + + reports { + xml.enabled = false + html.enabled = true + } +} +def classTree = 'build/intermediates/classes/debug' + +if (project.plugins.hasPlugin('java')) { + classTree = 'build/classes' +} +task findbugs(type: FindBugs) { + + description 'Run findbugs' + group 'verification' + + classes = fileTree(classTree) + source = fileTree('src/main/java/') + classpath = files() + + effort = 'max' + + excludeFilter = rootProject.file("findbugs-exclude.xml") + + reports { + xml.enabled = false + html.enabled = true + } + ignoreFailures = false +} + +//depend check +check.dependsOn('pmd') +check.dependsOn('findbugs') \ No newline at end of file diff --git a/gradle/gradle-mvn-push.gradle b/gradle/gradle-mvn-push.gradle index 9e795143..66196e32 100644 --- a/gradle/gradle-mvn-push.gradle +++ b/gradle/gradle-mvn-push.gradle @@ -125,14 +125,10 @@ task buildAndPublishRepo(dependsOn: ['build', 'uploadArchives']) { } } -//depend checkstyle -tasks.getByName("uploadArchives").dependsOn tasks.getByName("checkstyle") -tasks.getByName("bintrayUpload").dependsOn tasks.getByName("checkstyle") - tasks.getByName("bintrayUpload") { it.doFirst { if (!isReleaseBuild()) { throw new GradleException("bintrayUpload only support release version") } } -} \ No newline at end of file +} diff --git a/gradle/java-artifacts.gradle b/gradle/java-artifacts.gradle index 8f498a2e..9b204192 100644 --- a/gradle/java-artifacts.gradle +++ b/gradle/java-artifacts.gradle @@ -43,5 +43,4 @@ task buildAndPublishTinkerToLocalMaven(dependsOn: ['build', 'publishTinkerPatchP group = 'tinker' } -//depend checkstyle -project.tasks.getByName("check").dependsOn tasks.getByName("checkstyle") \ No newline at end of file +apply from: rootProject.file('gradle/check.gradle') \ No newline at end of file diff --git a/pmd-ruleset.xml b/pmd-ruleset.xml new file mode 100644 index 00000000..ca65331c --- /dev/null +++ b/pmd-ruleset.xml @@ -0,0 +1,44 @@ + + + + This ruleset was created from PMD.rul + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/library/TinkerLoadLibrary.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/library/TinkerLoadLibrary.java new file mode 100644 index 00000000..2d97d643 --- /dev/null +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/library/TinkerLoadLibrary.java @@ -0,0 +1,237 @@ +/* + * Tencent is pleased to support the open source community by making Tinker available. + * + * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tencent.tinker.lib.library; + +import android.content.Context; +import android.os.Build; + +import com.tencent.tinker.lib.tinker.Tinker; +import com.tencent.tinker.lib.tinker.TinkerLoadResult; +import com.tencent.tinker.lib.util.TinkerLog; +import com.tencent.tinker.loader.TinkerRuntimeException; +import com.tencent.tinker.loader.shareutil.ShareConstants; +import com.tencent.tinker.loader.shareutil.SharePatchFileUtil; +import com.tencent.tinker.loader.shareutil.ShareReflectUtil; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by zhangshaowen on 17/1/5. + */ + +public class TinkerLoadLibrary { + private static final String TAG = "Tinker.LoadLibrary"; + + /** + * you can use TinkerInstaller.loadLibrary replace your System.loadLibrary for auto update library! + * only support auto load lib/armeabi library from patch. + * for other library in lib/* or assets, + * you can load through {@code TinkerInstaller#loadLibraryFromTinker} + */ + public static void loadArmLibrary(Context context, String libName) { + if (libName == null || libName.isEmpty() || context == null) { + throw new TinkerRuntimeException("libName or context is null!"); + } + + Tinker tinker = Tinker.with(context); + if (tinker.isEnabledForNativeLib()) { + if (TinkerLoadLibrary.loadLibraryFromTinker(context, "lib/armeabi", libName)) { + return; + } + + } + System.loadLibrary(libName); + } + + /** + * you can use TinkerInstaller.loadArmV7Library replace your System.loadLibrary for auto update library! + * only support auto load lib/armeabi-v7a library from patch. + * for other library in lib/* or assets, + * you can load through {@code TinkerInstaller#loadLibraryFromTinker} + */ + public static void loadArmV7Library(Context context, String libName) { + if (libName == null || libName.isEmpty() || context == null) { + throw new TinkerRuntimeException("libName or context is null!"); + } + + Tinker tinker = Tinker.with(context); + if (tinker.isEnabledForNativeLib()) { + if (TinkerLoadLibrary.loadLibraryFromTinker(context, "lib/armeabi-v7a", libName)) { + return; + } + + } + System.loadLibrary(libName); + } + + /** + * sample usage for native library + * + * @param context + * @param relativePath such as lib/armeabi + * @param libName for the lib libTest.so, you can pass Test or libTest, or libTest.so + * @return boolean + * @throws UnsatisfiedLinkError + */ + public static boolean loadLibraryFromTinker(Context context, String relativePath, String libName) throws UnsatisfiedLinkError { + final Tinker tinker = Tinker.with(context); + + libName = libName.startsWith("lib") ? libName : "lib" + libName; + libName = libName.endsWith(".so") ? libName : libName + ".so"; + String relativeLibPath = relativePath + "/" + libName; + + //TODO we should add cpu abi, and the real path later + if (tinker.isEnabledForNativeLib() && tinker.isTinkerLoaded()) { + TinkerLoadResult loadResult = tinker.getTinkerLoadResultIfPresent(); + if (loadResult.libs != null) { + for (String name : loadResult.libs.keySet()) { + if (name.equals(relativeLibPath)) { + String patchLibraryPath = loadResult.libraryDirectory + "/" + name; + File library = new File(patchLibraryPath); + if (library.exists()) { + //whether we check md5 when load + boolean verifyMd5 = tinker.isTinkerLoadVerify(); + if (verifyMd5 && !SharePatchFileUtil.verifyFileMd5(library, loadResult.libs.get(name))) { + tinker.getLoadReporter().onLoadFileMd5Mismatch(library, ShareConstants.TYPE_LIBRARY); + } else { + System.load(patchLibraryPath); + TinkerLog.i(TAG, "loadLibraryFromTinker success:" + patchLibraryPath); + return true; + } + } + } + } + } + } + + return false; + } + + /** + * you can reflect your current abi to classloader library path + * as you don't need to use load*Library method above + * @param context + * @param currentABI + */ + public static void installNavitveLibraryABI(Context context, String currentABI) { + Tinker tinker = Tinker.with(context); + if (!tinker.isTinkerLoaded()) { + TinkerLog.i(TAG, "tinker is not loaded, just return"); + return; + } + TinkerLoadResult loadResult = tinker.getTinkerLoadResultIfPresent(); + if (loadResult.libs == null) { + TinkerLog.i(TAG, "tinker libs is null, just return"); + return; + } + File soDir = new File(loadResult.libraryDirectory, "lib/" + currentABI); + if (!soDir.exists()) { + TinkerLog.e(TAG, "current libraryABI folder is not exist, path: %s", soDir.getPath()); + return; + } + ClassLoader classLoader = context.getClassLoader(); + if (classLoader == null) { + TinkerLog.e(TAG, "classloader is null"); + return; + } + TinkerLog.i(TAG, "before hack classloader:" + classLoader.toString()); + + try { + installNativeLibraryPath(classLoader, soDir); + } catch (Throwable throwable) { + TinkerLog.e(TAG, "installNativeLibraryPath fail:" + throwable); + } + TinkerLog.i(TAG, "after hack classloader:" + classLoader.toString()); + } + + private static void installNativeLibraryPath(ClassLoader classLoader, File folder) + throws Throwable { + if (folder == null || !folder.exists()) { + TinkerLog.e(TAG, "installNativeLibraryPath, folder %s is illegal", folder); + return; + } + if (Build.VERSION.SDK_INT >= 23) { + try { + V23.install(classLoader, folder); + } catch (Throwable throwable) { + // install fail, try to treat it as v14 + TinkerLog.e(TAG, "installNativeLibraryPath, v23 fail, sdk: %d, error: %s", + Build.VERSION.SDK_INT, throwable.getMessage()); + + V14.install(classLoader, folder); + } + } else if (Build.VERSION.SDK_INT >= 14) { + V14.install(classLoader, folder); + } else { + V4.install(classLoader, folder); + } + } + + private static final class V4 { + private static void install(ClassLoader classLoader, File folder) throws Throwable { + String addPath = folder.getPath(); + Field pathField = ShareReflectUtil.findField(classLoader, "libPath"); + StringBuilder libPath = new StringBuilder((String) pathField.get(classLoader)); + libPath.append(':').append(addPath); + pathField.set(classLoader, libPath.toString()); + + Field libraryPathElementsFiled = ShareReflectUtil.findField(classLoader, "libraryPathElements"); + List libraryPathElements = (List) libraryPathElementsFiled.get(classLoader); + libraryPathElements.add(0, addPath); + libraryPathElementsFiled.set(classLoader, libraryPathElements); + } + } + + private static final class V14 { + private static void install(ClassLoader classLoader, File folder) throws Throwable { + Field pathListField = ShareReflectUtil.findField(classLoader, "pathList"); + Object dexPathList = pathListField.get(classLoader); + + ShareReflectUtil.expandFieldArray(dexPathList, "nativeLibraryDirectories", new File[]{folder}); + } + } + + private static final class V23 { + private static void install(ClassLoader classLoader, File folder) throws Throwable { + Field pathListField = ShareReflectUtil.findField(classLoader, "pathList"); + Object dexPathList = pathListField.get(classLoader); + + Field nativeLibraryDirectories = ShareReflectUtil.findField(dexPathList, "nativeLibraryDirectories"); + + List libDirs = (List) nativeLibraryDirectories.get(dexPathList); + libDirs.add(0, folder); + Field systemNativeLibraryDirectories = + ShareReflectUtil.findField(dexPathList, "systemNativeLibraryDirectories"); + List systemLibDirs = (List) systemNativeLibraryDirectories.get(dexPathList); + Method makePathElements = + ShareReflectUtil.findMethod(dexPathList, "makePathElements", List.class, File.class, List.class); + ArrayList suppressedExceptions = new ArrayList<>(); + libDirs.addAll(systemLibDirs); + Object[] elements = (Object[]) makePathElements. + invoke(dexPathList, libDirs, null, suppressedExceptions); + Field nativeLibraryPathElements = ShareReflectUtil.findField(dexPathList, "nativeLibraryPathElements"); + nativeLibraryPathElements.setAccessible(true); + nativeLibraryPathElements.set(dexPathList, elements); + } + } + +} diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/DexDiffPatchInternal.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/DexDiffPatchInternal.java index e5c9cd0d..5770fd71 100644 --- a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/DexDiffPatchInternal.java +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/DexDiffPatchInternal.java @@ -31,8 +31,6 @@ import com.tencent.tinker.loader.shareutil.ShareSecurityCheck; import com.tencent.tinker.loader.shareutil.ShareTinkerInternals; -import dalvik.system.DexFile; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -51,6 +49,12 @@ public class DexDiffPatchInternal extends BasePatchInternal { protected static final String TAG = "Tinker.DexDiffPatchInternal"; + protected static final int WAIT_ASYN_OAT_TIME = 5 * 1000; + protected static final int MAX_WAIT_COUNT = 30; + + private static ArrayList optFiles = new ArrayList<>(); + + protected static boolean tryRecoverDexFiles(Tinker manager, ShareSecurityCheck checker, Context context, String patchVersionDirectory, File patchFile) { if (!manager.isEnabledForDex()) { @@ -71,6 +75,43 @@ protected static boolean tryRecoverDexFiles(Tinker manager, ShareSecurityCheck c return result; } + protected static boolean checkDexOptFile(Context context, final File patchFile) { + if (optFiles.isEmpty()) { + return true; + } + + int size = optFiles.size() * 6; + if (size > MAX_WAIT_COUNT) { + size = MAX_WAIT_COUNT; + } + TinkerLog.i(TAG, "dex count: %d, final wait time: %d", optFiles.size(), size); + + for (int i = 0; i < size; i++) { + if (!checkAllDexOptFile(optFiles, i + 1)) { + try { + Thread.sleep(WAIT_ASYN_OAT_TIME); + } catch (InterruptedException e) { + TinkerLog.e(TAG, "thread sleep InterruptedException e:" + e); + } + } + } + + final Tinker manager = Tinker.with(context); + + // check again, if still can be found, just return + for (File file : optFiles) { + if (!SharePatchFileUtil.isLegalFile(file)) { + TinkerLog.e(TAG, "final parallel dex optimizer file %s is not exist, return false", file.getName()); + manager.getPatchReporter() + .onPatchDexOptFail(patchFile, file, file.getParentFile().getPath(), + file.getName(), new TinkerRuntimeException("dexOpt file:" + file.getName() + " is not exist")); + return false; + + } + } + return true; + } + private static boolean patchDexExtractViaDexDiff(Context context, String patchVersionDirectory, String meta, final File patchFile) { String dir = patchVersionDirectory + "/" + DEX_PATH + "/"; @@ -83,6 +124,7 @@ private static boolean patchDexExtractViaDexDiff(Context context, String patchVe File dexFiles = new File(dir); File[] files = dexFiles.listFiles(); + optFiles.clear(); if (files != null) { final String optimizeDexDirectory = patchVersionDirectory + "/" + DEX_OPTIMIZE_PATH + "/"; @@ -92,6 +134,11 @@ private static boolean patchDexExtractViaDexDiff(Context context, String patchVe TinkerLog.w(TAG, "patch recover, make optimizeDexDirectoryFile fail"); return false; } + // add opt files + for (File file : files) { + String outputPathName = SharePatchFileUtil.optimizedPathFor(file, optimizeDexDirectoryFile); + optFiles.add(new File(outputPathName)); + } TinkerLog.w(TAG, "patch recover, try to optimize dex file count:%d", files.length); @@ -121,44 +168,29 @@ public void onFailed(File dexFile, File optimizedDir, Throwable thr) { } } ); - //list again - if (isSuccess) { - for (File file : files) { - try { - if (!SharePatchFileUtil.isLegalFile(file)) { - TinkerLog.e(TAG, "single dex optimizer file %s is not exist, just return false", file); - return false; - } - String outputPathName = SharePatchFileUtil.optimizedPathFor(file, optimizeDexDirectoryFile); - File outputFile = new File(outputPathName); - if (!SharePatchFileUtil.isLegalFile(outputFile)) { - TinkerLog.e(TAG, "parallel dex optimizer file %s fail, optimize again", outputPathName); - long start = System.currentTimeMillis(); - DexFile.loadDex(file.getAbsolutePath(), outputPathName, 0); - TinkerLog.i(TAG, "success single dex optimize file, path: %s, use time: %d", file.getPath(), (System.currentTimeMillis() - start)); - if (!SharePatchFileUtil.isLegalFile(outputFile)) { - manager.getPatchReporter() - .onPatchDexOptFail(patchFile, file, optimizeDexDirectory, - file.getName(), new TinkerRuntimeException("dexOpt file:" + outputPathName + " is not exist")); - return false; - } - } - } catch (Throwable e) { - TinkerLog.e(TAG, "dex optimize or load failed, path:" + file.getPath()); - //delete file - SharePatchFileUtil.safeDeleteFile(file); - manager.getPatchReporter().onPatchDexOptFail(patchFile, file, optimizeDexDirectory, file.getName(), e); - return false; - } - } - } - return isSuccess; } return true; } + /** + * for ViVo or some other rom, they would make dex2oat asynchronous + * so we need to check whether oat file is actually generated. + * @param files + * @param count + * @return + */ + private static boolean checkAllDexOptFile(ArrayList files, int count) { + for (File file : files) { + if (!SharePatchFileUtil.isLegalFile(file)) { + TinkerLog.e(TAG, "parallel dex optimizer file %s is not exist, just wait %d times", file.getName(), count); + return false; + } + } + return true; + } + private static boolean extractDexDiffInternals(Context context, String dir, String meta, File patchFile, int type) { //parse ArrayList patchList = new ArrayList<>(); diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/UpgradePatch.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/UpgradePatch.java index 009e5964..fc7dfa6a 100644 --- a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/UpgradePatch.java +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/UpgradePatch.java @@ -140,6 +140,12 @@ public boolean tryPatch(Context context, String tempPatchPath, PatchResult patch return false; } + // check dex opt file at last, some phone such as ViVo like to change dex2oat to interpreted + if (!DexDiffPatchInternal.checkDexOptFile(context, destPatchFile)) { + TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, check dex opt file failed"); + return false; + } + final File patchInfoFile = manager.getPatchInfoFile(); if (!SharePatchInfo.rewritePatchInfoFileWithLock(patchInfoFile, newInfo, SharePatchFileUtil.getPatchInfoLockFile(patchDirectory))) { diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/service/AbstractResultService.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/service/AbstractResultService.java index 19061bae..95429503 100644 --- a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/service/AbstractResultService.java +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/service/AbstractResultService.java @@ -44,11 +44,15 @@ public static void runResultService(Context context, PatchResult result, String if (resultServiceClass == null) { throw new TinkerRuntimeException("resultServiceClass is null."); } - Intent intent = new Intent(); - intent.setClassName(context, resultServiceClass); - intent.putExtra(RESULT_EXTRA, result); + try { + Intent intent = new Intent(); + intent.setClassName(context, resultServiceClass); + intent.putExtra(RESULT_EXTRA, result); - context.startService(intent); + context.startService(intent); + } catch (Throwable throwable) { + TinkerLog.e(TAG, "run result service fail, exception:" + throwable); + } } @Override diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerInstaller.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerInstaller.java index 7ea178e6..9cb71ac0 100644 --- a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerInstaller.java +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerInstaller.java @@ -24,12 +24,7 @@ import com.tencent.tinker.lib.reporter.PatchReporter; import com.tencent.tinker.lib.service.AbstractResultService; import com.tencent.tinker.lib.util.TinkerLog; -import com.tencent.tinker.loader.TinkerRuntimeException; import com.tencent.tinker.loader.app.ApplicationLike; -import com.tencent.tinker.loader.shareutil.ShareConstants; -import com.tencent.tinker.loader.shareutil.SharePatchFileUtil; - -import java.io.File; /** * Created by zhangshaowen on 16/3/19. @@ -104,91 +99,4 @@ public static void onReceiveUpgradePatch(Context context, String patchLocation) public static void setLogIml(TinkerLog.TinkerLogImp imp) { TinkerLog.setTinkerLogImp(imp); } - - /** - * sample usage for native library - * - * @param context - * @param relativePath such as lib/armeabi - * @param libname for the lib libTest.so, you can pass Test or libTest, or libTest.so - * @return boolean - * @throws UnsatisfiedLinkError - */ - public static boolean loadLibraryFromTinker(Context context, String relativePath, String libname) throws UnsatisfiedLinkError { - final Tinker tinker = Tinker.with(context); - - libname = libname.startsWith("lib") ? libname : "lib" + libname; - libname = libname.endsWith(".so") ? libname : libname + ".so"; - String relativeLibPath = relativePath + "/" + libname; - - //TODO we should add cpu abi, and the real path later - if (tinker.isEnabledForNativeLib() && tinker.isTinkerLoaded()) { - TinkerLoadResult loadResult = tinker.getTinkerLoadResultIfPresent(); - if (loadResult.libs != null) { - for (String name : loadResult.libs.keySet()) { - if (name.equals(relativeLibPath)) { - String patchLibraryPath = loadResult.libraryDirectory + "/" + name; - File library = new File(patchLibraryPath); - if (library.exists()) { - //whether we check md5 when load - boolean verifyMd5 = tinker.isTinkerLoadVerify(); - if (verifyMd5 && !SharePatchFileUtil.verifyFileMd5(library, loadResult.libs.get(name))) { - tinker.getLoadReporter().onLoadFileMd5Mismatch(library, ShareConstants.TYPE_LIBRARY); - } else { - System.load(patchLibraryPath); - TinkerLog.i(TAG, "loadLibraryFromTinker success:" + patchLibraryPath); - return true; - } - } - } - } - } - } - - return false; - } - - /** - * you can use TinkerInstaller.loadLibrary replace your System.loadLibrary for auto update library! - * only support auto load lib/armeabi library from patch. - * for other library in lib/* or assets, - * you can load through {@code TinkerInstaller#loadLibraryFromTinker} - */ - public static void loadArmLibrary(Context context, String libName) { - if (libName == null || libName.isEmpty() || context == null) { - throw new TinkerRuntimeException("libName or context is null!"); - } - - Tinker tinker = Tinker.with(context); - if (tinker.isEnabledForNativeLib()) { - if (TinkerInstaller.loadLibraryFromTinker(context, "lib/armeabi", libName)) { - return; - } - - } - System.loadLibrary(libName); - } - - /** - * you can use TinkerInstaller.loadArmV7Library replace your System.loadLibrary for auto update library! - * only support auto load lib/armeabi-v7a library from patch. - * for other library in lib/* or assets, - * you can load through {@code TinkerInstaller#loadLibraryFromTinker} - */ - public static void loadArmV7Library(Context context, String libName) { - if (libName == null || libName.isEmpty() || context == null) { - throw new TinkerRuntimeException("libName or context is null!"); - } - - Tinker tinker = Tinker.with(context); - if (tinker.isEnabledForNativeLib()) { - if (TinkerInstaller.loadLibraryFromTinker(context, "lib/armeabi-v7a", libName)) { - return; - } - - } - System.loadLibrary(libName); - } - - } diff --git a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java index 204968f8..3b5b06f2 100644 --- a/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java +++ b/tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java @@ -42,6 +42,9 @@ public class TinkerLoadResult { public String currentVersion; public boolean versionChanged; + + public boolean systemOTA; + //@Nullable public File patchVersionDirectory; //@Nullable @@ -68,9 +71,11 @@ public class TinkerLoadResult { public boolean parseTinkerResult(Context context, Intent intentResult) { Tinker tinker = Tinker.with(context); loadCode = ShareIntentUtil.getIntentReturnCode(intentResult); - TinkerLog.i(TAG, "parseTinkerResult loadCode:%d", loadCode); costTime = ShareIntentUtil.getIntentPatchCostTime(intentResult); + systemOTA = ShareIntentUtil.getBooleanExtra(intentResult, ShareIntentUtil.INTENT_PATCH_SYSTEM_OTA, false); + + TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, systemOTA:%b", loadCode, systemOTA); //@Nullable final String oldVersion = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_OLD_VERSION); //@Nullable diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java index 7fc6a66b..3fa21b51 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java @@ -106,6 +106,10 @@ public static AndroidNClassLoader inject(PathClassLoader originClassLoader, Appl // } public Class findClass(String name) throws ClassNotFoundException { + // loader class use default pathClassloader to load + if (name != null && name.startsWith("com.tencent.tinker.loader.") && !name.equals("com.tencent.tinker.loader.TinkerTestDexLoad")) { + return originClassLoader.loadClass(name); + } return super.findClass(name); } diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/SystemClassLoaderAdder.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/SystemClassLoaderAdder.java index 3f0f057e..6c8199fa 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/SystemClassLoaderAdder.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/SystemClassLoaderAdder.java @@ -110,7 +110,7 @@ private static boolean checkDexInstall(ClassLoader classLoader) throws ClassNotF } /** - * Installer for platform versions 19. + * Installer for platform versions 23. */ private static final class V23 { diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerLoader.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerLoader.java index 0869e0b5..103dfd39 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerLoader.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerLoader.java @@ -204,6 +204,7 @@ private void tryLoadPatchFilesInternal(TinkerApplication app, int tinkerFlag, bo } //only work for art platform oat boolean isSystemOTA = ShareTinkerInternals.isVmArt() && ShareTinkerInternals.isSystemOTA(patchInfo.fingerPrint); + resultIntent.putExtra(ShareIntentUtil.INTENT_PATCH_SYSTEM_OTA, isSystemOTA); //we should first try rewrite patch info file, if there is a error, we can't load jar if (isSystemOTA diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/ApplicationLike.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/ApplicationLike.java index df3d558f..ca0a9059 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/ApplicationLike.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/ApplicationLike.java @@ -33,34 +33,16 @@ public abstract class ApplicationLike implements ApplicationLifeCycle { private final long applicationStartMillisTime; private final int tinkerFlags; private final boolean tinkerLoadVerifyFlag; - private Resources[] resources; - private ClassLoader[] classLoader; - private AssetManager[] assetManager; + public ApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, - long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, - Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) { + long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) { this.application = application; this.tinkerFlags = tinkerFlags; this.tinkerLoadVerifyFlag = tinkerLoadVerifyFlag; this.applicationStartElapsedTime = applicationStartElapsedTime; this.applicationStartMillisTime = applicationStartMillisTime; this.tinkerResultIntent = tinkerResultIntent; - this.resources = resources; - this.classLoader = classLoader; - this.assetManager = assetManager; - } - - public void setResources(Resources resources) { - this.resources[0] = resources; - } - - public void setAssetManager(AssetManager assetManager) { - this.assetManager[0] = assetManager; - } - - public void setClassLoader(ClassLoader classLoader) { - this.classLoader[0] = classLoader; } public Application getApplication() { @@ -116,4 +98,21 @@ public void onConfigurationChanged(Configuration newConfig) { public void onBaseContextAttached(Context base) { } + //some get methods that may be overwrite + public Resources getResources(Resources resources) { + return resources; + } + + public ClassLoader getClassLoader(ClassLoader classLoader) { + return classLoader; + } + + public AssetManager getAssets(AssetManager assetManager) { + return assetManager; + } + + public Object getSystemService(String name, Object service) { + return service; + } } + diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/DefaultApplicationLike.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/DefaultApplicationLike.java index f0367db2..eabf146e 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/DefaultApplicationLike.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/DefaultApplicationLike.java @@ -23,9 +23,7 @@ import android.app.Application; import android.content.Context; import android.content.Intent; -import android.content.res.AssetManager; import android.content.res.Configuration; -import android.content.res.Resources; import android.util.Log; /** @@ -35,9 +33,8 @@ public class DefaultApplicationLike extends ApplicationLike { private static final String TAG = "Tinker.DefaultAppLike"; public DefaultApplicationLike(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); + long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) { + super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); } @Override diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/TinkerApplication.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/TinkerApplication.java index 7abbbd4b..bcdab701 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/TinkerApplication.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/TinkerApplication.java @@ -31,7 +31,6 @@ import com.tencent.tinker.loader.TinkerUncaughtHandler; import com.tencent.tinker.loader.shareutil.ShareConstants; import com.tencent.tinker.loader.shareutil.ShareIntentUtil; -import com.tencent.tinker.loader.shareutil.ShareReflectUtil; import com.tencent.tinker.loader.shareutil.ShareTinkerInternals; import java.lang.reflect.Constructor; @@ -55,7 +54,7 @@ public abstract class TinkerApplication extends Application { * dex only, library only, all support * default: TINKER_ENABLE_ALL */ - private final int tinkerFlags; + private final int tinkerFlags; /** * whether verify md5 when we load dex or lib * they store at data/data/package, and we had verity them at the :patch process. @@ -68,13 +67,10 @@ public abstract class TinkerApplication extends Application { /** * if we have load patch, we should use safe mode */ - private boolean useSafeMode; + private boolean useSafeMode; private Intent tinkerResultIntent; - private Object delegate = null; - private Resources[] resources = new Resources[1]; - private ClassLoader[] classLoader = new ClassLoader[1]; - private AssetManager[] assetManager = new AssetManager[1]; + private ApplicationLike applicationLike = null; private long applicationStartElapsedTime; private long applicationStartMillisTime; @@ -103,24 +99,23 @@ protected TinkerApplication(int tinkerFlags, String delegateClassName) { this(tinkerFlags, delegateClassName, TinkerLoader.class.getName(), false); } - private Object createDelegate() { + private ApplicationLike createDelegate() { try { // Use reflection to create the delegate so it doesn't need to go into the primary dex. // And we can also patch it Class delegateClass = Class.forName(delegateClassName, false, getClassLoader()); - Constructor constructor = delegateClass.getConstructor(Application.class, int.class, boolean.class, long.class, long.class, - Intent.class, Resources[].class, ClassLoader[].class, AssetManager[].class); - return constructor.newInstance(this, tinkerFlags, tinkerLoadVerifyFlag, - applicationStartElapsedTime, applicationStartMillisTime, - tinkerResultIntent, resources, classLoader, assetManager); + Constructor constructor = delegateClass.getConstructor(Application.class, int.class, boolean.class, + long.class, long.class, Intent.class); + return (ApplicationLike) constructor.newInstance(this, tinkerFlags, tinkerLoadVerifyFlag, + applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); } catch (Throwable e) { throw new TinkerRuntimeException("createDelegate failed", e); } } private synchronized void ensureDelegate() { - if (delegate == null) { - delegate = createDelegate(); + if (applicationLike == null) { + applicationLike = createDelegate(); } } @@ -134,12 +129,7 @@ private void onBaseContextAttached(Context base) { applicationStartMillisTime = System.currentTimeMillis(); loadTinker(); ensureDelegate(); - try { - Method method = ShareReflectUtil.findMethod(delegate, "onBaseContextAttached", Context.class); - method.invoke(delegate, base); - } catch (Throwable t) { - throw new TinkerRuntimeException("onBaseContextAttached method not found", t); - } + applicationLike.onBaseContextAttached(base); //reset save mode if (useSafeMode) { String processName = ShareTinkerInternals.getProcessName(this); @@ -176,44 +166,26 @@ private void loadTinker() { } } - private void delegateMethod(String methodName) { - if (delegate != null) { - try { - Method method = ShareReflectUtil.findMethod(delegate, methodName, new Class[0]); - method.invoke(delegate, new Object[0]); - } catch (Throwable t) { - throw new TinkerRuntimeException(String.format("%s method not found", methodName), t); - } - } - } - @Override public void onCreate() { super.onCreate(); ensureDelegate(); - delegateMethod("onCreate"); + applicationLike.onCreate(); } @Override public void onTerminate() { super.onTerminate(); - delegateMethod("onTerminate"); + if (applicationLike != null) { + applicationLike.onTerminate(); + } } @Override public void onLowMemory() { super.onLowMemory(); - delegateMethod("onLowMemory"); - } - - private void delegateTrimMemory(int level) { - if (delegate != null) { - try { - Method method = ShareReflectUtil.findMethod(delegate, "onTrimMemory", int.class); - method.invoke(delegate, level); - } catch (Throwable t) { - throw new TinkerRuntimeException("onTrimMemory method not found", t); - } + if (applicationLike != null) { + applicationLike.onLowMemory(); } } @@ -221,48 +193,53 @@ private void delegateTrimMemory(int level) { @Override public void onTrimMemory(int level) { super.onTrimMemory(level); - delegateTrimMemory(level); - } - - private void delegateConfigurationChanged(Configuration newConfig) { - if (delegate != null) { - try { - Method method = ShareReflectUtil.findMethod(delegate, "onConfigurationChanged", Configuration.class); - method.invoke(delegate, newConfig); - } catch (Throwable t) { - throw new TinkerRuntimeException("onConfigurationChanged method not found", t); - } + if (applicationLike != null) { + applicationLike.onTrimMemory(level); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - delegateConfigurationChanged(newConfig); + if (applicationLike != null) { + applicationLike.onConfigurationChanged(newConfig); + } } @Override public Resources getResources() { - if (resources[0] != null) { - return resources[0]; + Resources resources = super.getResources(); + if (applicationLike != null) { + return applicationLike.getResources(resources); } - return super.getResources(); + return resources; } @Override public ClassLoader getClassLoader() { - if (classLoader[0] != null) { - return classLoader[0]; + ClassLoader classLoader = super.getClassLoader(); + if (applicationLike != null) { + return applicationLike.getClassLoader(classLoader); } - return super.getClassLoader(); + return classLoader; } @Override public AssetManager getAssets() { - if (assetManager[0] != null) { - return assetManager[0]; + AssetManager assetManager = super.getAssets(); + if (applicationLike != null) { + return applicationLike.getAssets(assetManager); + } + return assetManager; + } + + @Override + public Object getSystemService(String name) { + Object service = super.getSystemService(name); + if (applicationLike != null) { + return applicationLike.getSystemService(name, service); } - return super.getAssets(); + return service; } public void setUseSafeMode(boolean useSafeMode) { diff --git a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareIntentUtil.java b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareIntentUtil.java index 965fb4cd..7cf48852 100644 --- a/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareIntentUtil.java +++ b/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareIntentUtil.java @@ -41,6 +41,8 @@ public class ShareIntentUtil { public static final String INTENT_PATCH_EXCEPTION = "intent_patch_exception"; public static final String INTENT_PATCH_PACKAGE_PATCH_CHECK = "intent_patch_package_patch_check"; public static final String INTENT_PATCH_PACKAGE_CONFIG = "intent_patch_package_config"; + public static final String INTENT_PATCH_SYSTEM_OTA = "intent_patch_system_ota"; + private static final String TAG = "ShareIntentUtil"; public static void setIntentReturnCode(Intent intent, int code) { diff --git a/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/TinkerPatchPlugin.groovy b/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/TinkerPatchPlugin.groovy index d8203ec0..9fe162e9 100644 --- a/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/TinkerPatchPlugin.groovy +++ b/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/TinkerPatchPlugin.groovy @@ -67,10 +67,6 @@ class TinkerPatchPlugin implements Plugin { def android = project.extensions.android - //add the tinker anno resource to the package exclude option - android.packagingOptions.exclude("META-INF/services/javax.annotation.processing.Processor") - android.packagingOptions.exclude("TinkerAnnoApplication.tmpl") - //open jumboMode android.dexOptions.jumboMode = true diff --git a/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/task/TinkerPatchSchemaTask.groovy b/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/task/TinkerPatchSchemaTask.groovy index c9f11441..87d674ad 100644 --- a/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/task/TinkerPatchSchemaTask.groovy +++ b/tinker-build/tinker-patch-gradle-plugin/src/main/groovy/com/tencent/tinker/build/gradle/task/TinkerPatchSchemaTask.groovy @@ -66,15 +66,15 @@ public class TinkerPatchSchemaTask extends DefaultTask { .setNewApk(buildApkPath) .setOutBuilder(outputFolder) .setIgnoreWarning(configuration.ignoreWarning) - .setDexFilePattern(configuration.dex.pattern) - .setDexLoaderPattern(configuration.dex.loader) + .setDexFilePattern(new ArrayList(configuration.dex.pattern)) + .setDexLoaderPattern(new ArrayList(configuration.dex.loader)) .setDexMode(configuration.dex.dexMode) - .setSoFilePattern(configuration.lib.pattern) - .setResourceFilePattern(configuration.res.pattern) - .setResourceIgnoreChangePattern(configuration.res.ignoreChange) + .setSoFilePattern(new ArrayList(configuration.lib.pattern)) + .setResourceFilePattern(new ArrayList(configuration.res.pattern)) + .setResourceIgnoreChangePattern(new ArrayList(configuration.res.ignoreChange)) .setResourceLargeModSize(configuration.res.largeModSize) .setUseApplyResource(configuration.buildConfig.usingResourceMapping) - .setConfigFields(configuration.packageConfig.getFields()) + .setConfigFields(new HashMap(configuration.packageConfig.getFields())) .setSevenZipPath(configuration.sevenZip.path) .setUseSign(configuration.useSign) diff --git a/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/decoder/DexDiffDecoder.java b/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/decoder/DexDiffDecoder.java index 2fce2357..77d4e980 100644 --- a/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/decoder/DexDiffDecoder.java +++ b/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/decoder/DexDiffDecoder.java @@ -279,7 +279,7 @@ private void generatePatchedDexInfoFile() { } private void diffDexPairAndFillRelatedInfo(File oldDexFile, File newDexFile, RelatedInfo relatedInfo) { - File tempFullPatchDexPath = new File(config.mOutFolder + File.separator + TypedValue.DEX_TEMP_PATCH_DIR + File.separator + "full"); + File tempFullPatchDexPath = new File(config.mOutFolder + File.separator + TypedValue.DEX_TEMP_PATCH_DIR); final String dexName = getRelativeDexName(oldDexFile, newDexFile); File dexDiffOut = getOutputPath(newDexFile).toFile(); diff --git a/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/info/PatchInfo.java b/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/info/PatchInfo.java index 2adf51a4..1ac70a60 100644 --- a/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/info/PatchInfo.java +++ b/tinker-build/tinker-patch-lib/src/main/java/com/tencent/tinker/build/info/PatchInfo.java @@ -23,13 +23,10 @@ */ public class PatchInfo { - private final Configuration config; - private final PatchInfoGen infoGen; public PatchInfo(Configuration config) { - this.config = config; infoGen = new PatchInfoGen(config); } diff --git a/tinker-sample-android/app/src/main/java/tinker/sample/android/app/MainActivity.java b/tinker-sample-android/app/src/main/java/tinker/sample/android/app/MainActivity.java index 187b119a..0c152361 100644 --- a/tinker-sample-android/app/src/main/java/tinker/sample/android/app/MainActivity.java +++ b/tinker-sample-android/app/src/main/java/tinker/sample/android/app/MainActivity.java @@ -30,6 +30,7 @@ import android.widget.Button; import android.widget.TextView; +import com.tencent.tinker.lib.library.TinkerLoadLibrary; import com.tencent.tinker.lib.tinker.Tinker; import com.tencent.tinker.lib.tinker.TinkerInstaller; import com.tencent.tinker.loader.shareutil.ShareConstants; diff --git a/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java b/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java index 4efb0597..9233951e 100644 --- a/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java +++ b/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java @@ -20,8 +20,6 @@ import android.app.Application; import android.content.Context; import android.content.Intent; -import android.content.res.AssetManager; -import android.content.res.Resources; import android.os.Build; import android.support.multidex.MultiDex; @@ -65,9 +63,8 @@ public class SampleApplicationLike extends DefaultApplicationLike { private static final String TAG = "Tinker.SampleApplicationLike"; public SampleApplicationLike(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); + long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) { + super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); } /** diff --git a/tinker-sample-android/gradle.properties b/tinker-sample-android/gradle.properties index 6b9e5667..25a8de5a 100644 --- a/tinker-sample-android/gradle.properties +++ b/tinker-sample-android/gradle.properties @@ -17,4 +17,4 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -TINKER_VERSION=1.7.6 +TINKER_VERSION=1.7.7