Skip to content

Commit 30c03bd

Browse files
committed
[enhancement] remove splash oat Activity
[enhancement] add interpret mode after first oat to fast first launch time s
1 parent 694a534 commit 30c03bd

File tree

33 files changed

+400
-577
lines changed

33 files changed

+400
-577
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ 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())
97-
.replaceAll("%OTA_SPLASH_ACTIVITY%", "" + ca.otaSplashActivity());
96+
.replaceAll("%TINKER_LOAD_VERIFY_FLAG%", "" + ca.loadVerifyFlag());
9897

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

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

-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,4 @@
3939
int flags();
4040

4141
boolean loadVerifyFlag() default false;
42-
43-
boolean otaSplashActivity() default false;
4442
}

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%, %OTA_SPLASH_ACTIVITY%);
13+
super(%TINKER_FLAGS%, "%APPLICATION_LIFE_CYCLE%", "%TINKER_LOADER_CLASS%", %TINKER_LOAD_VERIFY_FLAG%);
1414
}
1515

1616
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class BasePatchInternal {
3636

3737
protected static final String DEX_PATH = ShareConstants.DEX_PATH;
3838
protected static final String SO_PATH = ShareConstants.SO_PATH;
39-
protected static final String DEX_OPTIMIZE_PATH = ShareConstants.DEX_OPTIMIZE_PATH;
39+
protected static final String DEX_OPTIMIZE_PATH = ShareConstants.DEFAULT_DEX_OPTIMIZE_PATH;
4040
protected static final int MAX_EXTRACT_ATTEMPTS = ShareConstants.MAX_EXTRACT_ATTEMPTS;
4141
protected static final String DEX_META_FILE = ShareConstants.DEX_META_FILE;
4242
protected static final String SO_META_FILE = ShareConstants.SO_META_FILE;

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.io.IOException;
3939
import java.io.InputStream;
4040
import java.util.ArrayList;
41+
import java.util.Arrays;
4142
import java.util.List;
4243
import java.util.Vector;
4344
import java.util.zip.ZipEntry;
@@ -146,14 +147,14 @@ private static boolean patchDexExtractViaDexDiff(Context context, String patchVe
146147
optFiles.add(new File(outputPathName));
147148
}
148149

149-
TinkerLog.w(TAG, "patch recover, try to optimize dex file count:%d", files.length);
150+
TinkerLog.i(TAG, "patch recover, try to optimize dex file count:%d, optimizeDexDirectory:%s", files.length, optimizeDexDirectory);
150151

151152
// only use parallel dex optimizer for art
152153
if (ShareTinkerInternals.isVmArt()) {
153154
failOptDexFile.clear();
154155
// try parallel dex optimizer
155156
TinkerParallelDexOptimizer.optimizeAll(
156-
files, optimizeDexDirectoryFile,
157+
Arrays.asList(files), optimizeDexDirectoryFile,
157158
new TinkerParallelDexOptimizer.ResultCallback() {
158159
long startTime;
159160

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

+19-20
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,27 @@ public boolean tryPatch(Context context, String tempPatchPath, PatchResult patch
6464
return false;
6565
}
6666

67-
//it is a new patch, so we should not find a exist
68-
SharePatchInfo oldInfo = manager.getTinkerLoadResultIfPresent().patchInfo;
6967
String patchMd5 = SharePatchFileUtil.getMD5(patchFile);
70-
7168
if (patchMd5 == null) {
7269
TinkerLog.e(TAG, "UpgradePatch tryPatch:patch md5 is null, just return");
7370
return false;
7471
}
72+
TinkerLog.i(TAG, "UpgradePatch tryPatch:patchMd5:%s", patchMd5);
73+
74+
//check ok, we can real recover a new patch
75+
final String patchDirectory = manager.getPatchDirectory().getAbsolutePath();
7576

76-
//use md5 as version
77-
patchResult.patchVersion = patchMd5;
77+
File patchInfoLockFile = SharePatchFileUtil.getPatchInfoLockFile(patchDirectory);
78+
File patchInfoFile = SharePatchFileUtil.getPatchInfoFile(patchDirectory);
7879

80+
SharePatchInfo oldInfo = SharePatchInfo.readAndCheckPropertyWithLock(patchInfoFile, patchInfoLockFile);
81+
82+
//it is a new patch, so we should not find a exist
7983
SharePatchInfo newInfo;
8084

8185
//already have patch
8286
if (oldInfo != null) {
83-
if (oldInfo.oldVersion == null || oldInfo.newVersion == null) {
87+
if (oldInfo.oldVersion == null || oldInfo.newVersion == null || oldInfo.oatDir == null) {
8488
TinkerLog.e(TAG, "UpgradePatch tryPatch:onPatchInfoCorrupted");
8589
manager.getPatchReporter().onPatchInfoCorrupted(patchFile, oldInfo.oldVersion, oldInfo.newVersion);
8690
return false;
@@ -91,26 +95,23 @@ public boolean tryPatch(Context context, String tempPatchPath, PatchResult patch
9195
manager.getPatchReporter().onPatchVersionCheckFail(patchFile, oldInfo, patchMd5);
9296
return false;
9397
}
94-
newInfo = new SharePatchInfo(oldInfo.oldVersion, patchMd5, Build.FINGERPRINT);
98+
// if it is interpret now, use changing flag to wait main process
99+
final String finalOatDir = oldInfo.oatDir.equals(ShareConstants.INTERPRET_DEX_OPTIMIZE_PATH)
100+
? ShareConstants.CHANING_DEX_OPTIMIZE_PATH : oldInfo.oatDir;
101+
newInfo = new SharePatchInfo(oldInfo.oldVersion, patchMd5, Build.FINGERPRINT, finalOatDir);
95102
} else {
96-
newInfo = new SharePatchInfo("", patchMd5, Build.FINGERPRINT);
103+
newInfo = new SharePatchInfo("", patchMd5, Build.FINGERPRINT, ShareConstants.DEFAULT_DEX_OPTIMIZE_PATH);
97104
}
98105

99-
//check ok, we can real recover a new patch
100-
final String patchDirectory = manager.getPatchDirectory().getAbsolutePath();
101-
102-
TinkerLog.i(TAG, "UpgradePatch tryPatch:patchMd5:%s", patchMd5);
103-
106+
//it is a new patch, we first delete if there is any files
107+
//don't delete dir for faster retry
108+
// SharePatchFileUtil.deleteDir(patchVersionDirectory);
104109
final String patchName = SharePatchFileUtil.getPatchVersionDirectory(patchMd5);
105110

106111
final String patchVersionDirectory = patchDirectory + "/" + patchName;
107112

108113
TinkerLog.i(TAG, "UpgradePatch tryPatch:patchVersionDirectory:%s", patchVersionDirectory);
109114

110-
//it is a new patch, we first delete if there is any files
111-
//don't delete dir for faster retry
112-
// SharePatchFileUtil.deleteDir(patchVersionDirectory);
113-
114115
//copy file
115116
File destPatchFile = new File(patchVersionDirectory + "/" + SharePatchFileUtil.getPatchVersionFile(patchMd5));
116117

@@ -150,9 +151,7 @@ public boolean tryPatch(Context context, String tempPatchPath, PatchResult patch
150151
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, check dex opt file failed");
151152
}
152153

153-
final File patchInfoFile = manager.getPatchInfoFile();
154-
155-
if (!SharePatchInfo.rewritePatchInfoFileWithLock(patchInfoFile, newInfo, SharePatchFileUtil.getPatchInfoLockFile(patchDirectory))) {
154+
if (!SharePatchInfo.rewritePatchInfoFileWithLock(patchInfoFile, newInfo, patchInfoLockFile)) {
156155
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, rewrite patch info failed");
157156
manager.getPatchReporter().onPatchInfoCorrupted(patchFile, newInfo.oldVersion, newInfo.newVersion);
158157
return false;

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

+25-3
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@ public void onLoadPatchVersionChanged(String oldVersion, String newVersion, File
105105
}
106106
}
107107

108+
/**
109+
* After system ota, we will try to load dex with interpret mode
110+
* @param type type define as following
111+
* {@code ShareConstants.TYPE_INTERPRET_OK} it is ok, using interpret mode
112+
* {@code ShareConstants.TYPE_INTERPRET_GET_INSTRUCTION_SET_ERROR} get instruction set from exist oat file fail
113+
* {@code ShareConstants.TYPE_INTERPRET_COMMAND_ERROR} use command line to generate interpret oat file fail
114+
* @param e
115+
*/
116+
@Override
117+
public void onLoadInterpret(int type, Throwable e) {
118+
TinkerLog.i(TAG, "patch loadReporter onLoadInterpret: type: %d, throwable: %s",
119+
type, e);
120+
switch (type) {
121+
case ShareConstants.TYPE_INTERPRET_GET_INSTRUCTION_SET_ERROR:
122+
TinkerLog.e(TAG, "patch loadReporter onLoadInterpret fail, can get instruction set from existed oat file");
123+
break;
124+
case ShareConstants.TYPE_INTERPRET_COMMAND_ERROR:
125+
TinkerLog.e(TAG, "patch loadReporter onLoadInterpret fail, command line to interpret return error");
126+
break;
127+
case ShareConstants.TYPE_INTERPRET_OK:
128+
TinkerLog.i(TAG, "patch loadReporter onLoadInterpret ok");
129+
break;
130+
}
131+
}
132+
108133
/**
109134
* some files is not found,
110135
* we'd like to recover the old patch with {@link TinkerPatchService} in OldPatchProcessor mode
@@ -204,9 +229,6 @@ public void onLoadException(Throwable e, int errorCode) {
204229
ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context);
205230
TinkerLog.i(TAG, "dex exception disable tinker forever with sp");
206231
break;
207-
case ShareConstants.ERROR_LOAD_EXCEPTION_DEX_OPT:
208-
TinkerLog.i(TAG, "patch load parallel dex opt exception: %s", e);
209-
break;
210232
case ShareConstants.ERROR_LOAD_EXCEPTION_RESOURCE:
211233
if (e.getMessage().contains(ShareConstants.CHECK_RES_INSTALL_FAIL)) {
212234
TinkerLog.e(TAG, "patch loadReporter onLoadException: tinker res check fail:" + e.getMessage());

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

+9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ public interface LoadReporter {
5252
*/
5353
void onLoadPatchVersionChanged(String oldVersion, String newVersion, File patchDirectoryFile, String currentPatchName);
5454

55+
/**
56+
* After system ota, we will try to load dex with interpret mode
57+
* @param type type define as following
58+
* {@code ShareConstants.TYPE_INTERPRET_OK} it is ok, using interpret mode
59+
* {@code ShareConstants.TYPE_INTERPRET_GET_INSTRUCTION_SET_ERROR} get instruction set from exist oat file fail
60+
* {@code ShareConstants.TYPE_INTERPRET_COMMAND_ERROR} use command line to generate interpret oat file fail
61+
* @param e
62+
*/
63+
void onLoadInterpret(int type, Throwable e);
5564
/**
5665
* the load patch process is end, we can see the cost times and the return code
5766
* return codes are define in {@link com.tencent.tinker.loader.shareutil.ShareConstants}

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

+21-9
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ public class TinkerLoadResult {
4040
public SharePatchInfo patchInfo;
4141
//@Nullable
4242
public String currentVersion;
43+
//@Nullable
44+
public String oatDir;
45+
46+
public boolean versionChanged;
4347

44-
public boolean versionChanged;
48+
public boolean useInterpretMode;
4549

46-
public boolean systemOTA;
50+
public boolean systemOTA;
4751

4852
//@Nullable
4953
public File patchVersionDirectory;
@@ -74,10 +78,13 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
7478

7579
costTime = ShareIntentUtil.getIntentPatchCostTime(intentResult);
7680
systemOTA = ShareIntentUtil.getBooleanExtra(intentResult, ShareIntentUtil.INTENT_PATCH_SYSTEM_OTA, false);
81+
oatDir = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_OAT_DIR);
82+
useInterpretMode = ShareConstants.INTERPRET_DEX_OPTIMIZE_PATH.equals(oatDir);
83+
7784
final boolean isMainProcess = tinker.isMainProcess();
7885

79-
TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, process name:%s, main process:%b, systemOTA:%b",
80-
loadCode, ShareTinkerInternals.getProcessName(context), isMainProcess, systemOTA);
86+
TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, process name:%s, main process:%b, systemOTA:%b, oatDir:%s, useInterpretMode:%b",
87+
loadCode, ShareTinkerInternals.getProcessName(context), isMainProcess, systemOTA, oatDir, useInterpretMode);
8188

8289
//@Nullable
8390
final String oldVersion = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_OLD_VERSION);
@@ -87,7 +94,6 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
8794
final File patchDirectory = tinker.getPatchDirectory();
8895
final File patchInfoFile = tinker.getPatchInfoFile();
8996

90-
9197
if (oldVersion != null && newVersion != null) {
9298
if (isMainProcess) {
9399
currentVersion = newVersion;
@@ -107,7 +113,7 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
107113
resourceDirectory = new File(patchVersionDirectory, ShareConstants.RES_PATH);
108114
resourceFile = new File(resourceDirectory, ShareConstants.RES_NAME);
109115
}
110-
patchInfo = new SharePatchInfo(oldVersion, newVersion, Build.FINGERPRINT);
116+
patchInfo = new SharePatchInfo(oldVersion, newVersion, Build.FINGERPRINT, oatDir);
111117
versionChanged = !(oldVersion.equals(newVersion));
112118
}
113119

@@ -123,9 +129,6 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
123129
case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_LOAD_EXCEPTION:
124130
errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_DEX;
125131
break;
126-
case ShareConstants.ERROR_LOAD_PATCH_VERSION_PARALLEL_DEX_OPT_EXCEPTION:
127-
errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_DEX_OPT;
128-
break;
129132
case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_LOAD_EXCEPTION:
130133
errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_RESOURCE;
131134
break;
@@ -308,6 +311,12 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
308311
tinker.getLoadReporter().onLoadFileMd5Mismatch(resourceFile,
309312
ShareConstants.TYPE_RESOURCE);
310313
break;
314+
case ShareConstants.ERROR_LOAD_PATCH_GET_OTA_INSTRUCTION_SET_EXCEPTION:
315+
tinker.getLoadReporter().onLoadInterpret(ShareConstants.TYPE_INTERPRET_GET_INSTRUCTION_SET_ERROR, ShareIntentUtil.getIntentInterpretException(intentResult));
316+
break;
317+
case ShareConstants.ERROR_LOAD_PATCH_OTA_INTERPRET_ONLY_EXCEPTION:
318+
tinker.getLoadReporter().onLoadInterpret(ShareConstants.TYPE_INTERPRET_COMMAND_ERROR, ShareIntentUtil.getIntentInterpretException(intentResult));
319+
break;
311320
case ShareConstants.ERROR_LOAD_OK:
312321
TinkerLog.i(TAG, "oh yeah, tinker load all success");
313322
tinker.setTinkerLoaded(true);
@@ -317,6 +326,9 @@ public boolean parseTinkerResult(Context context, Intent intentResult) {
317326

318327
packageConfig = ShareIntentUtil.getIntentPackageConfig(intentResult);
319328

329+
if (useInterpretMode) {
330+
tinker.getLoadReporter().onLoadInterpret(ShareConstants.TYPE_INTERPRET_OK, null);
331+
}
320332
if (isMainProcess && versionChanged) {
321333
//change the old version to new
322334
tinker.getLoadReporter().onLoadPatchVersionChanged(oldVersion, newVersion, patchDirectory, patchVersionDirectory.getName());
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
<manifest package="com.tencent.tinker.loader"
22
xmlns:android="http://schemas.android.com/apk/res/android">
33
<application>
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"/>
164
</application>
175

186
</manifest>

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@
2424

2525
import com.tencent.tinker.loader.shareutil.ShareReflectUtil;
2626

27-
import dalvik.system.DexFile;
28-
import dalvik.system.PathClassLoader;
29-
3027
import java.io.File;
3128
import java.io.IOException;
3229
import java.lang.reflect.Field;
3330
import java.lang.reflect.Method;
3431
import java.util.ArrayList;
3532
import java.util.List;
3633

34+
import dalvik.system.DexFile;
35+
import dalvik.system.PathClassLoader;
36+
3737
/**
3838
* Created by zhangshaowen on 16/7/24.
3939
*/

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

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class SystemClassLoaderAdder {
5151
@SuppressLint("NewApi")
5252
public static void installDexes(Application application, PathClassLoader loader, File dexOptDir, List<File> files)
5353
throws Throwable {
54+
Log.i(TAG, "installDexes dexOptDir: " + dexOptDir.getAbsolutePath() + ", dex size:" + files.size());
5455

5556
if (!files.isEmpty()) {
5657
ClassLoader classLoader = loader;

0 commit comments

Comments
 (0)