Skip to content

Commit

Permalink
1. prepare for release 1.7.7
Browse files Browse the repository at this point in the history
2.  fix xposed judgment
  • Loading branch information
shwenzhang committed Jan 13, 2017
1 parent 853bb9e commit 314ab53
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 45 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## Tinker
[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/tinker/blob/master/LICENSE)
[![Release Version](https://img.shields.io/badge/release-1.7.6-red.svg)](https://github.com/Tencent/tinker/releases)
[![Release Version](https://img.shields.io/badge/release-1.7.7-red.svg)](https://github.com/Tencent/tinker/releases)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/tinker/pulls)
[![WeChat Approved](https://img.shields.io/badge/Wechat_Approved-1.7.6-red.svg)](https://github.com/Tencent/tinker/wiki)
[![WeChat Approved](https://img.shields.io/badge/Wechat_Approved-1.7.7-red.svg)](https://github.com/Tencent/tinker/wiki)

Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk.

Expand All @@ -14,7 +14,7 @@ Add tinker-gradle-plugin as a dependency in your main `build.gradle` in the root
```gradle
buildscript {
dependencies {
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.6')
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.7')
}
}
```
Expand All @@ -24,9 +24,9 @@ Then you need to "apply" the plugin and add dependencies by adding the following
```gradle
dependencies {
//optional, help to generate the final application
provided('com.tencent.tinker:tinker-android-anno:1.7.6')
provided('com.tencent.tinker:tinker-android-anno:1.7.7')
//tinker's main Android lib
compile('com.tencent.tinker:tinker-android-lib:1.7.6')
compile('com.tencent.tinker:tinker-android-lib:1.7.7')
}
...
...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
public class DexDiffPatchInternal extends BasePatchInternal {
protected static final String TAG = "Tinker.DexDiffPatchInternal";

protected static final int WAIT_ASYN_OAT_TIME = 6 * 1000;
protected static final int WAIT_ASYN_OAT_TIME = 8 * 1000;
protected static final int MAX_WAIT_COUNT = 30;

private static ArrayList<File> optFiles = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,14 @@
class TinkerResourcePatcher {
private static final String TAG = "Tinker.ResourcePatcher";
private static final String TEST_ASSETS_VALUE = "only_use_to_test_tinker_resource.txt";
private static final String MIUI_RESOURCE_CLASSNAME = "android.content.res.MiuiResources";
// private static final String MIUI_RESOURCE_CLASSNAME = "android.content.res.MiuiResources";

// original object
private static Collection<WeakReference<Resources>> references = null;
private static Object currentActivityThread = null;
private static AssetManager newAssetManager = null;
private static ArrayMap<?, WeakReference<Resources>> activeResources19 = null;
// private static ArrayMap<?, WeakReference<?>> resourceImpls = null;
private static HashMap<?, WeakReference<Resources>> activeResources7 = null;

// method
private static Method addAssetPathMethod = null;
private static Method ensureStringBlocksMethod = null;
Expand All @@ -64,7 +63,7 @@ class TinkerResourcePatcher {
private static Field resourcePackagesFiled = null;
// private static Field publicSourceDirField = null;

private static boolean isMiuiSystem = false;
// private static boolean isMiuiSystem = false;

public static void isResourceCanPatch(Context context) throws Throwable {
// - Replace mResDir to point to the external resource file instead of the .apk. This is
Expand Down Expand Up @@ -121,7 +120,7 @@ public static void isResourceCanPatch(Context context) throws Throwable {
try {
Field fMActiveResources = resourcesManagerClass.getDeclaredField("mActiveResources");
fMActiveResources.setAccessible(true);
activeResources19 =
ArrayMap<?, WeakReference<Resources>> activeResources19 =
(ArrayMap<?, WeakReference<Resources>>) fMActiveResources.get(resourcesManager);
references = activeResources19.values();
} catch (NoSuchFieldException ignore) {
Expand All @@ -135,7 +134,7 @@ public static void isResourceCanPatch(Context context) throws Throwable {
} else {
Field fMActiveResources = activityThread.getDeclaredField("mActiveResources");
fMActiveResources.setAccessible(true);
activeResources7 =
HashMap<?, WeakReference<Resources>> activeResources7 =
(HashMap<?, WeakReference<Resources>>) fMActiveResources.get(currentActivityThread);
references = activeResources7.values();
}
Expand All @@ -152,8 +151,8 @@ public static void isResourceCanPatch(Context context) throws Throwable {
resourcesImplFiled.setAccessible(true);
}

final Resources resources = context.getResources();
isMiuiSystem = resources != null && MIUI_RESOURCE_CLASSNAME.equals(resources.getClass().getName());
// final Resources resources = context.getResources();
// isMiuiSystem = resources != null && MIUI_RESOURCE_CLASSNAME.equals(resources.getClass().getName());

// try {
// publicSourceDirField = ShareReflectUtil.findField(ApplicationInfo.class, "publicSourceDir");
Expand Down Expand Up @@ -211,7 +210,7 @@ public static void monkeyPatchExistingResources(Context context, String external
implAssets.set(resourceImpl, newAssetManager);
}

fixMiuiTypedArrayIssue(resources);
clearPreloadTypedArrayIssue(resources);

resources.updateConfiguration(resources.getConfiguration(), resources.getDisplayMetrics());
}
Expand All @@ -232,13 +231,14 @@ public static void monkeyPatchExistingResources(Context context, String external
* Resource has mTypedArrayPool field, which just like Message Poll to reduce gc
* MiuiResource change TypedArray to MiuiTypedArray, but it get string block from offset instead of assetManager
*/
private static void fixMiuiTypedArrayIssue(Resources resources) {
private static void clearPreloadTypedArrayIssue(Resources resources) {
// Perform this trick not only in Miui system since we can't predict if any other
// manufacturer would do the same modification to Android.
// if (!isMiuiSystem) {
// return;
// }
Log.w(TAG, "Miui system found, try to clear MiuiTypedArray cache!");

Log.w(TAG, "try to clear typedArray cache!");
// Clear typedArray cache.
try {
Field typedArrayPoolField = ShareReflectUtil.findField(Resources.class, "mTypedArrayPool");
Expand All @@ -253,6 +253,7 @@ private static void fixMiuiTypedArrayIssue(Resources resources) {
final Object newTypedArrayPool = typedArrayConstructor.newInstance(poolSize);
typedArrayPoolField.set(resources, newTypedArrayPool);
} catch (Throwable ignored) {
Log.e(TAG, "clearPreloadTypedArrayIssue failed, ignore error: " + ignored);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@

/**
* Created by zhangshaowen on 17/1/12.
*
* TODO:
* Thanks for Android Fragmentation
* hold the issue https://github.com/Tencent/tinker/issues/302
*/

public class TinkerResourcesKey {

private static final class V24 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,19 @@ public class TinkerUncaughtHandler implements Thread.UncaughtExceptionHandler {

private final File crashFile;
private final Context context;
private final Thread.UncaughtExceptionHandler ueh;

public TinkerUncaughtHandler(Context context) {
this.context = context;
ueh = Thread.getDefaultUncaughtExceptionHandler();
crashFile = SharePatchFileUtil.getPatchLastCrashFile(context);
}

@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e(TAG, "catch exception when loading tinker:" + Log.getStackTraceString(ex));
ueh.uncaughtException(thread, ex);

if (crashFile != null) {
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();

Expand All @@ -67,8 +71,8 @@ public void uncaughtException(Thread thread, Throwable ex) {
} finally {
SharePatchFileUtil.closeQuietly(pw);
}
android.os.Process.killProcess(android.os.Process.myPid());
}
}
android.os.Process.killProcess(android.os.Process.myPid());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
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.lib.util.TinkerLog;
import com.tencent.tinker.loader.shareutil.ShareConstants;
import com.tencent.tinker.loader.shareutil.ShareTinkerInternals;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,42 @@ public void uncaughtException(Thread thread, Throwable ex) {
* If it use Xposed, we can just clean patch or mention user to uninstall it.
*/
private void tinkerPreVerifiedCrashHandler(Throwable ex) {
if (Utils.isXposedExists(ex)) {
//method 1
ApplicationLike applicationLike = TinkerManager.getTinkerApplicationLike();
if (applicationLike == null || applicationLike.getApplication() == null) {
return;
Throwable throwable = ex;
boolean isXposed = false;
while (throwable != null) {
if (!isXposed) {
isXposed = Utils.isXposedExists(throwable);
}

if (!TinkerApplicationHelper.isTinkerLoadSuccess(applicationLike)) {
return;
}
boolean isCausedByXposed = false;
//for art, we can't know the actually crash type
//just ignore art
if (ex instanceof IllegalAccessError && ex.getMessage().contains(DALVIK_XPOSED_CRASH)) {
//for dalvik, we know the actual crash type
isCausedByXposed = true;
}

if (isCausedByXposed) {
SampleTinkerReport.onXposedCrash();
TinkerLog.e(TAG, "have xposed: just clean tinker");
//kill all other process to ensure that all process's code is the same.
ShareTinkerInternals.killAllOtherProcess(applicationLike.getApplication());

TinkerApplicationHelper.cleanPatch(applicationLike);
ShareTinkerInternals.setTinkerDisableWithSharedPreferences(applicationLike.getApplication());
if (isXposed) {
//method 1
ApplicationLike applicationLike = TinkerManager.getTinkerApplicationLike();
if (applicationLike == null || applicationLike.getApplication() == null) {
return;
}

if (!TinkerApplicationHelper.isTinkerLoadSuccess(applicationLike)) {
return;
}
boolean isCausedByXposed = false;
//for art, we can't know the actually crash type
//just ignore art
if (throwable instanceof IllegalAccessError && throwable.getMessage().contains(DALVIK_XPOSED_CRASH)) {
//for dalvik, we know the actual crash type
isCausedByXposed = true;
}

if (isCausedByXposed) {
SampleTinkerReport.onXposedCrash();
TinkerLog.e(TAG, "have xposed: just clean tinker");
//kill all other process to ensure that all process's code is the same.
ShareTinkerInternals.killAllOtherProcess(applicationLike.getApplication());

TinkerApplicationHelper.cleanPatch(applicationLike);
ShareTinkerInternals.setTinkerDisableWithSharedPreferences(applicationLike.getApplication());
return;
}
}
throwable = throwable.getCause();
}
}

Expand Down

0 comments on commit 314ab53

Please sign in to comment.