Skip to content

Commit 28f1852

Browse files
committed
1. [bugfix] fix large file bsdiff memory error # 348
2. [bugfix] edit apk-parser to 1.2.0, fix issue #249 3. [bugfix] fix webview resource error #374 4. [enhancement] add tinker ota splash activity 5. [enhancement] use origin classloader to load Application with AndroidNClassloader
1 parent e32a8ef commit 28f1852

File tree

30 files changed

+463
-101
lines changed

30 files changed

+463
-101
lines changed

third-party/bsdiff-util/src/main/java/com/tencent/tinker/bsdiff/BSPatch.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ public static int patchLessMemory(RandomAccessFile oldFile, int oldsize, byte[]
110110
return RETURN_DIFF_FILE_ERR;
111111
}
112112

113-
int commentLenPos = oldsize - extLen - 2;
114-
if (commentLenPos <= 2) {
115-
return RETURN_OLD_FILE_ERR;
116-
}
113+
// int commentLenPos = oldsize - extLen - 2;
114+
// if (commentLenPos <= 2) {
115+
// return RETURN_OLD_FILE_ERR;
116+
// }
117117

118118
DataInputStream diffIn = new DataInputStream(new ByteArrayInputStream(diffBuf, 0, diffSize));
119119

@@ -167,10 +167,10 @@ public static int patchLessMemory(RandomAccessFile oldFile, int oldsize, byte[]
167167
return RETURN_DIFF_FILE_ERR;
168168
}
169169
for (int i = 0; i < ctrl[0]; i++) {
170-
if (oldpos + i == commentLenPos) {
171-
oldBuffer[i] = 0;
172-
oldBuffer[i + 1] = 0;
173-
}
170+
// if (oldpos + i == commentLenPos) {
171+
// oldBuffer[i] = 0;
172+
// oldBuffer[i + 1] = 0;
173+
// }
174174

175175
if ((oldpos + i >= 0) && (oldpos + i < oldsize)) {
176176
buffer[i] += oldBuffer[i];

tinker-android/tinker-android-anno/src/main/java/com/tencent/tinker/anno/AnnotationProcessor.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ private void processDefaultLifeCycle(Set<? extends Element> elements) {
9393
.replaceAll("%APPLICATION_LIFE_CYCLE%", lifeCyclePackageName + "." + lifeCycleClassName)
9494
.replaceAll("%TINKER_FLAGS%", "" + ca.flags())
9595
.replaceAll("%TINKER_LOADER_CLASS%", "" + loaderClassName)
96-
.replaceAll("%TINKER_LOAD_VERIFY_FLAG%", "" + ca.loadVerifyFlag());
96+
.replaceAll("%TINKER_LOAD_VERIFY_FLAG%", "" + ca.loadVerifyFlag())
97+
.replaceAll("%OTA_SPLASH_ACTIVITY%", "" + ca.otaSplashActivity());
9798

9899
try {
99100
JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(applicationPackageName + "." + applicationClassName);

tinker-android/tinker-android-anno/src/main/java/com/tencent/tinker/anno/DefaultLifeCycle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@
4040

4141
boolean loadVerifyFlag() default false;
4242

43-
43+
boolean otaSplashActivity() default false;
4444
}

tinker-android/tinker-android-anno/src/main/resources/TinkerAnnoApplication.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import com.tencent.tinker.loader.app.TinkerApplication;
1010
public class %APPLICATION% extends TinkerApplication {
1111

1212
public %APPLICATION%() {
13-
super(%TINKER_FLAGS%, "%APPLICATION_LIFE_CYCLE%", "%TINKER_LOADER_CLASS%", %TINKER_LOAD_VERIFY_FLAG%);
13+
super(%TINKER_FLAGS%, "%APPLICATION_LIFE_CYCLE%", "%TINKER_LOADER_CLASS%", %TINKER_LOAD_VERIFY_FLAG%, %OTA_SPLASH_ACTIVITY%);
1414
}
1515

1616
}

tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/patch/ResDiffPatchInternal.java

+2
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ private static boolean extractResourceDiffInternals(Context context, String dir,
195195
ResUtil.extractTinkerEntry(newApk, modZipEntry, out);
196196
totalEntryCount++;
197197
}
198+
// set comment back
199+
out.setComment(oldApk.getComment());
198200
} finally {
199201
if (out != null) {
200202
out.close();

tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/reporter/DefaultLoadReporter.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public DefaultLoadReporter(Context context) {
5858
*/
5959
@Override
6060
public void onLoadPatchListenerReceiveFail(File patchFile, int errorCode) {
61-
TinkerLog.i(TAG, "patch loadReporter onLoadPatchListenerReceiveFail: patch receive fail:%s, code:%d",
61+
TinkerLog.i(TAG, "patch loadReporter onLoadPatchListenerReceiveFail: patch receive fail: %s, code: %d",
6262
patchFile.getAbsolutePath(), errorCode);
6363
}
6464

@@ -122,7 +122,7 @@ public void onLoadPatchVersionChanged(String oldVersion, String newVersion, File
122122
*/
123123
@Override
124124
public void onLoadFileNotFound(File file, int fileType, boolean isDirectory) {
125-
TinkerLog.i(TAG, "patch loadReporter onLoadFileNotFound: patch file not found: %s, fileType:%d, isDirectory:%b",
125+
TinkerLog.i(TAG, "patch loadReporter onLoadFileNotFound: patch file not found: %s, fileType: %d, isDirectory: %b",
126126
file.getAbsolutePath(), fileType, isDirectory);
127127

128128
checkAndCleanPatch();
@@ -142,7 +142,7 @@ public void onLoadFileNotFound(File file, int fileType, boolean isDirectory) {
142142
*/
143143
@Override
144144
public void onLoadFileMd5Mismatch(File file, int fileType) {
145-
TinkerLog.i(TAG, "patch load Reporter onLoadFileMd5Mismatch: patch file md5 mismatch file: %s, fileType:%d", file.getAbsolutePath(), fileType);
145+
TinkerLog.i(TAG, "patch load Reporter onLoadFileMd5Mismatch: patch file md5 mismatch file: %s, fileType: %d", file.getAbsolutePath(), fileType);
146146
//clean patch for safety
147147
checkAndCleanPatch();
148148
}
@@ -174,7 +174,7 @@ public void onLoadPatchInfoCorrupted(String oldVersion, String newVersion, File
174174
*/
175175
@Override
176176
public void onLoadResult(File patchDirectory, int loadCode, long cost) {
177-
TinkerLog.i(TAG, "patch loadReporter onLoadResult: patch load result, path:%s, code:%d, cost:%d", patchDirectory.getAbsolutePath(), loadCode, cost);
177+
TinkerLog.i(TAG, "patch loadReporter onLoadResult: patch load result, path:%s, code: %d, cost: %dms", patchDirectory.getAbsolutePath(), loadCode, cost);
178178
//you can just report the result here
179179
}
180180

@@ -251,7 +251,7 @@ public void onLoadException(Throwable e, int errorCode) {
251251
@Override
252252
public void onLoadPackageCheckFail(File patchFile, int errorCode) {
253253
TinkerLog.i(TAG, "patch loadReporter onLoadPackageCheckFail: "
254-
+ "load patch package check fail file path:%s, errorCode:%d", patchFile.getAbsolutePath(), errorCode);
254+
+ "load patch package check fail file path: %s, errorCode: %d", patchFile.getAbsolutePath(), errorCode);
255255
checkAndCleanPatch();
256256
}
257257

tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/reporter/DefaultPatchReporter.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void onPatchServiceStart(Intent intent) {
7373
*/
7474
@Override
7575
public void onPatchPackageCheckFail(File patchFile, int errorCode) {
76-
TinkerLog.i(TAG, "patchReporter onPatchPackageCheckFail: package check failed. path:%s, code:%d",
76+
TinkerLog.i(TAG, "patchReporter onPatchPackageCheckFail: package check failed. path: %s, code: %d",
7777
patchFile.getAbsolutePath(), errorCode);
7878
//only meta corrupted, need to delete temp files. others is just in the check time!
7979
if (errorCode == ShareConstants.ERROR_PACKAGE_CHECK_DEX_META_CORRUPTED
@@ -94,7 +94,7 @@ public void onPatchPackageCheckFail(File patchFile, int errorCode) {
9494
*/
9595
@Override
9696
public void onPatchVersionCheckFail(File patchFile, SharePatchInfo oldPatchInfo, String patchFileVersion) {
97-
TinkerLog.i(TAG, "patchReporter onPatchVersionCheckFail: patch version exist. path:%s, version:%s",
97+
TinkerLog.i(TAG, "patchReporter onPatchVersionCheckFail: patch version exist. path: %s, version: %s",
9898
patchFile.getAbsolutePath(), patchFileVersion);
9999
//no need to delete temp files, because it is only in the check time!
100100
}
@@ -114,7 +114,7 @@ public void onPatchVersionCheckFail(File patchFile, SharePatchInfo oldPatchInfo,
114114
*/
115115
@Override
116116
public void onPatchTypeExtractFail(File patchFile, File extractTo, String filename, int fileType) {
117-
TinkerLog.i(TAG, "patchReporter onPatchTypeExtractFail: file extract fail type:%s, path:%s, extractTo:%s, filename:%s",
117+
TinkerLog.i(TAG, "patchReporter onPatchTypeExtractFail: file extract fail type: %s, path: %s, extractTo: %s, filename: %s",
118118
ShareTinkerInternals.getTypeString(fileType), patchFile.getPath(), extractTo.getPath(), filename);
119119
//delete temp files
120120
Tinker.with(context).cleanPatchByVersion(patchFile);
@@ -130,7 +130,7 @@ public void onPatchTypeExtractFail(File patchFile, File extractTo, String filena
130130
*/
131131
@Override
132132
public void onPatchDexOptFail(File patchFile, File dexFile, String optDirectory, String dexName, Throwable t) {
133-
TinkerLog.i(TAG, "patchReporter onPatchDexOptFail: dex opt fail path:%s, dexPath:%s, optDir:%s, dexName:%s",
133+
TinkerLog.i(TAG, "patchReporter onPatchDexOptFail: dex opt fail path: %s, dexPath: %s, optDir: %s, dexName: %s",
134134
patchFile.getAbsolutePath(), dexFile.getPath(), optDirectory, dexName);
135135
TinkerLog.printErrStackTrace(TAG, t, "onPatchDexOptFail:");
136136
//delete temp files
@@ -146,7 +146,7 @@ public void onPatchDexOptFail(File patchFile, File dexFile, String optDirectory,
146146
*/
147147
@Override
148148
public void onPatchResult(File patchFile, boolean success, long cost) {
149-
TinkerLog.i(TAG, "patchReporter onPatchResult: patch all result path:%s, success:%b, cost:%d",
149+
TinkerLog.i(TAG, "patchReporter onPatchResult: patch all result path: %s, success: %b, cost: %d",
150150
patchFile.getAbsolutePath(), success, cost);
151151
//you can just report the result here
152152
}
@@ -161,7 +161,7 @@ public void onPatchResult(File patchFile, boolean success, long cost) {
161161
*/
162162
@Override
163163
public void onPatchInfoCorrupted(File patchFile, String oldVersion, String newVersion) {
164-
TinkerLog.i(TAG, "patchReporter onPatchInfoCorrupted: patch info is corrupted. old:%s, new:%s",
164+
TinkerLog.i(TAG, "patchReporter onPatchInfoCorrupted: patch info is corrupted. old: %s, new: %s",
165165
oldVersion, newVersion);
166166
//patch.info is corrupted, just clean all patch
167167
Tinker.with(context).cleanPatch();
@@ -177,7 +177,7 @@ public void onPatchInfoCorrupted(File patchFile, String oldVersion, String newVe
177177
*/
178178
@Override
179179
public void onPatchException(File patchFile, Throwable e) {
180-
TinkerLog.i(TAG, "patchReporter onPatchException: patch exception path:%s, throwable:%s",
180+
TinkerLog.i(TAG, "patchReporter onPatchException: patch exception path: %s, throwable: %s",
181181
patchFile.getAbsolutePath(), e.getMessage());
182182
TinkerLog.e(TAG, "tinker patch exception, welcome to submit issue to us: https://github.com/Tencent/tinker/issues");
183183
// if (e.getMessage().contains(ShareConstants.CHECK_VM_PROPERTY_FAIL)) {

tinker-android/tinker-android-lib/src/main/java/com/tencent/tinker/lib/tinker/TinkerLoadResult.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
7474

7575
costTime = ShareIntentUtil.getIntentPatchCostTime(intentResult);
7676
systemOTA = ShareIntentUtil.getBooleanExtra(intentResult, ShareIntentUtil.INTENT_PATCH_SYSTEM_OTA, false);
77+
final boolean isMainProcess = tinker.isMainProcess();
78+
79+
TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, process name:%s, main process:%b, systemOTA:%b",
80+
loadCode, ShareTinkerInternals.getProcessName(context), isMainProcess, systemOTA);
7781

78-
TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, systemOTA:%b", loadCode, systemOTA);
7982
//@Nullable
8083
final String oldVersion = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_OLD_VERSION);
8184
//@Nullable
@@ -84,8 +87,6 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
8487
final File patchDirectory = tinker.getPatchDirectory();
8588
final File patchInfoFile = tinker.getPatchInfoFile();
8689

87-
final boolean isMainProcess = tinker.isMainProcess();
88-
8990

9091
if (oldVersion != null && newVersion != null) {
9192
if (isMainProcess) {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
<manifest
2-
package="com.tencent.tinker.loader">
3-
1+
<manifest package="com.tencent.tinker.loader"
2+
xmlns:android="http://schemas.android.com/apk/res/android">
43
<application>
5-
4+
<activity
5+
android:name=".splash.TinkerOTASplashActivity"
6+
android:configChanges="keyboardHidden"
7+
android:excludeFromRecents="true"
8+
android:exported="false"
9+
android:launchMode="singleTop"
10+
android:process=":otasplash">
11+
</activity>
12+
<receiver
13+
android:name=".splash.TinkerSplashBroadCast"
14+
android:exported="false"
15+
android:process=":otasplash"/>
616
</application>
717

818
</manifest>

tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AbstractTinkerLoader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@
2525
* Created by zhangshaowen on 16/4/30.
2626
*/
2727
public abstract class AbstractTinkerLoader {
28-
abstract public Intent tryLoad(TinkerApplication app, int tinkerFlag, boolean tinkerLoadVerifyFlag);
28+
abstract public Intent tryLoad(TinkerApplication app);
2929
}

tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/AndroidNClassLoader.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.app.Application;
2121
import android.content.Context;
2222
import android.os.Build;
23+
import android.text.TextUtils;
2324

2425
import com.tencent.tinker.loader.shareutil.ShareReflectUtil;
2526

@@ -39,16 +40,21 @@
3940
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
4041
class AndroidNClassLoader extends PathClassLoader {
4142
static ArrayList<DexFile> oldDexFiles = new ArrayList<>();
42-
PathClassLoader originClassLoader;
43+
private final PathClassLoader originClassLoader;
44+
private String applicationClassName;
4345

44-
private AndroidNClassLoader(String dexPath, PathClassLoader parent) {
46+
private AndroidNClassLoader(String dexPath, PathClassLoader parent, Application application) {
4547
super(dexPath, parent.getParent());
4648
originClassLoader = parent;
49+
String name = application.getClass().getName();
50+
if (name != null && !name.equals("android.app.Application")) {
51+
applicationClassName = name;
52+
}
4753
}
4854

49-
private static AndroidNClassLoader createAndroidNClassLoader(PathClassLoader original) throws Exception {
55+
private static AndroidNClassLoader createAndroidNClassLoader(PathClassLoader original, Application application) throws Exception {
5056
//let all element ""
51-
AndroidNClassLoader androidNClassLoader = new AndroidNClassLoader("", original);
57+
AndroidNClassLoader androidNClassLoader = new AndroidNClassLoader("", original, application);
5258
Field originPathList = ShareReflectUtil.findField(original, "pathList");
5359
Object originPathListObject = originPathList.get(original);
5460
//should reflect definingContext also
@@ -90,7 +96,7 @@ private static void reflectPackageInfoClassloader(Application application, Class
9096
}
9197

9298
public static AndroidNClassLoader inject(PathClassLoader originClassLoader, Application application) throws Exception {
93-
AndroidNClassLoader classLoader = createAndroidNClassLoader(originClassLoader);
99+
AndroidNClassLoader classLoader = createAndroidNClassLoader(originClassLoader, application);
94100
reflectPackageInfoClassloader(application, classLoader);
95101
return classLoader;
96102
}
@@ -107,7 +113,8 @@ public static AndroidNClassLoader inject(PathClassLoader originClassLoader, Appl
107113

108114
public Class<?> findClass(String name) throws ClassNotFoundException {
109115
// loader class use default pathClassloader to load
110-
if (name != null && name.startsWith("com.tencent.tinker.loader.") && !name.equals("com.tencent.tinker.loader.TinkerTestDexLoad")) {
116+
if ((name != null && name.startsWith("com.tencent.tinker.loader.") && !name.equals("com.tencent.tinker.loader.TinkerTestDexLoad"))
117+
|| (applicationClassName != null && TextUtils.equals(applicationClassName, name))) {
111118
return originClassLoader.loadClass(name);
112119
}
113120
return super.findClass(name);

tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerDexLoader.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
package com.tencent.tinker.loader;
1818

1919
import android.annotation.TargetApi;
20-
import android.app.Application;
2120
import android.content.Intent;
2221
import android.os.Build;
2322
import android.util.Log;
2423

24+
import com.tencent.tinker.loader.app.TinkerApplication;
2525
import com.tencent.tinker.loader.shareutil.ShareConstants;
2626
import com.tencent.tinker.loader.shareutil.ShareDexDiffPatchInfo;
2727
import com.tencent.tinker.loader.shareutil.ShareIntentUtil;
@@ -62,7 +62,7 @@ private TinkerDexLoader() {
6262
* @param application The application.
6363
*/
6464
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
65-
public static boolean loadTinkerJars(Application application, boolean tinkerLoadVerifyFlag, String directory, Intent intentResult, boolean isSystemOTA) {
65+
public static boolean loadTinkerJars(final TinkerApplication application, String directory, Intent intentResult, boolean isSystemOTA) {
6666
if (dexList.isEmpty()) {
6767
Log.w(TAG, "there is no dex to load");
6868
return true;
@@ -92,7 +92,7 @@ public static boolean loadTinkerJars(Application application, boolean tinkerLoad
9292
String path = dexPath + info.realName;
9393
File file = new File(path);
9494

95-
if (tinkerLoadVerifyFlag) {
95+
if (application.isTinkerLoadVerifyFlag()) {
9696
long start = System.currentTimeMillis();
9797
String checkMd5 = isArtPlatForm ? info.destMd5InArt : info.destMd5InDvm;
9898
if (!SharePatchFileUtil.verifyDexFileMd5(file, checkMd5)) {
@@ -108,9 +108,12 @@ public static boolean loadTinkerJars(Application application, boolean tinkerLoad
108108
}
109109

110110
if (isSystemOTA) {
111+
boolean launchSuccess = ShareTinkerInternals.launcherSplashProcess(application,
112+
application.getSplashActivity(), legalFiles.size());
113+
111114
parallelOTAResult = true;
112115
parallelOTAThrowable = null;
113-
Log.w(TAG, "systemOTA, try parallel oat dexes!!!!!");
116+
Log.w(TAG, "systemOTA, try parallel oat dexes, launch result:" + launchSuccess);
114117

115118
TinkerParallelDexOptimizer.optimizeAll(
116119
legalFiles, optimizeDir,
@@ -136,6 +139,9 @@ public void onFailed(File dexFile, File optimizedDir, Throwable thr) {
136139
}
137140
}
138141
);
142+
143+
ShareTinkerInternals.sendSplashEndBroadcast(application);
144+
139145
if (!parallelOTAResult) {
140146
Log.e(TAG, "parallel oat dexes failed");
141147
intentResult.putExtra(ShareIntentUtil.INTENT_PATCH_EXCEPTION, parallelOTAThrowable);

0 commit comments

Comments
 (0)