This is an automated email from the ASF dual-hosted git repository.
luckychen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git
The following commit(s) were added to refs/heads/master by this push:
new 5e8d9ac [Android] Fix Crash in NotifyLayout (#2902)
5e8d9ac is described below
commit 5e8d9ac935d6fbadd2469d83540426cc30b4e676
Author: YorkShen <[email protected]>
AuthorDate: Mon Sep 16 16:20:43 2019 +0800
[Android] Fix Crash in NotifyLayout (#2902)
There is a concurrent read/write operation to `RenderManager::pages_`
during `CoreSideInPlatform::NotifyLayout`where MainThread is reading
`RenderManager::pages_` while other thread may be writing to it.
```
std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>,
std::__ndk1::allocator<char> >::__is_long() const at string:1266
(inlined by) std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::size() const at
string:905
(inlined by) std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>
>::compare(std::__ndk1::basic_string_view<char, std::__ndk1::char_traits<char>
>) const at string:3455
(inlined by) std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>
>::compare(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>,
std::__ndk1::allocator<char> > const&) const at string:3473
(inlined by) bool std::__ndk1::operator< <char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>
>(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>,
std::__ndk1::allocator<char> > const&, std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) at
string:3693
(inlined by) std::__ndk1::less<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >
>::operator()(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>,
std::__ndk1::allocator<char> > const&, std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) const at
__functional_base:55
(inlined by)
std::__ndk1::__map_value_compare<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*>, std::__ndk1::less<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >,
true>::operator()(std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std: [...]
(inlined by)
std::__ndk1::__tree_iterator<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*>,
std::__ndk1::__tree_node<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*>, void*>*, int>
std::__ndk1::__tree<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char [...]
std::__ndk1::__tree_iterator<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*>,
std::__ndk1::__tree_node<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*>, void*>*, int>
std::__ndk1::__tree<std::__ndk1::__value_type<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1 [...]
std::__ndk1::map<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >,
WeexCore::RenderPageBase*, std::__ndk1::less<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > >,
std::__ndk1::allocator<std::__ndk1::pair<std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const,
WeexCore::RenderPageBase*> > >::find(std::__ndk1::basic_string<char,
std::__ndk1::char_tra [...]
(inlined by)
WeexCore::RenderManager::GetPage(std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) at
render_manager.cpp:472
WeexCore::CoreSideInPlatform::NotifyLayout(std::__ndk1::basic_string<char,
std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&) at
core_side_in_platform.cpp:223
```
---
.../java/com/taobao/weex/WeexFrameRateControl.java | 52 ++++++++++++----------
.../com/taobao/weex/bridge/WXBridgeManager.java | 6 +--
2 files changed, 32 insertions(+), 26 deletions(-)
diff --git
a/android/sdk/src/main/java/com/taobao/weex/WeexFrameRateControl.java
b/android/sdk/src/main/java/com/taobao/weex/WeexFrameRateControl.java
index eef4d5c..14817fd 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WeexFrameRateControl.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WeexFrameRateControl.java
@@ -26,14 +26,15 @@ import android.annotation.SuppressLint;
import android.os.Build;
import android.util.Log;
import android.view.Choreographer;
+import com.taobao.weex.bridge.WXBridgeManager;
import com.taobao.weex.common.WXErrorCode;
import java.lang.ref.WeakReference;
public class WeexFrameRateControl {
private static final long VSYNC_FRAME = 1000 / 60;
private WeakReference<VSyncListener> mListener;
- private final Choreographer mChoreographer;
- private final Choreographer.FrameCallback mVSyncFrameCallback;
+ private Choreographer mChoreographer;
+ private Choreographer.FrameCallback mVSyncFrameCallback;
private final Runnable runnable;
public interface VSyncListener {
@@ -43,27 +44,32 @@ public class WeexFrameRateControl {
public WeexFrameRateControl(VSyncListener listener) {
mListener = new WeakReference<>(listener);
if (Build.VERSION.SDK_INT >
Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
- mChoreographer = Choreographer.getInstance();
- mVSyncFrameCallback = new Choreographer.FrameCallback() {
- @SuppressLint("NewApi")
- @Override
- public void doFrame(long frameTimeNanos) {
- VSyncListener vSyncListener;
- if (mListener != null && (vSyncListener=mListener.get())
!= null) {
- try {
- vSyncListener.OnVSync();
-
mChoreographer.postFrameCallback(mVSyncFrameCallback);
- }catch (UnsatisfiedLinkError e){
- if(vSyncListener instanceof WXSDKInstance){
- ((WXSDKInstance) vSyncListener).onRenderError(
-
WXErrorCode.WX_DEGRAD_ERR_INSTANCE_CREATE_FAILED.getErrorCode(),
- Log.getStackTraceString(e));
- }
- }
- }
- }
- };
- runnable = null;
+ WXBridgeManager.getInstance().post(new Runnable() {
+ @Override
+ public void run() {
+ mChoreographer = Choreographer.getInstance();
+ mVSyncFrameCallback = new Choreographer.FrameCallback() {
+ @SuppressLint("NewApi")
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ VSyncListener vSyncListener;
+ if (mListener != null &&
(vSyncListener=mListener.get()) != null) {
+ try {
+ vSyncListener.OnVSync();
+
mChoreographer.postFrameCallback(mVSyncFrameCallback);
+ }catch (UnsatisfiedLinkError e){
+ if(vSyncListener instanceof WXSDKInstance){
+ ((WXSDKInstance)
vSyncListener).onRenderError(
+
WXErrorCode.WX_DEGRAD_ERR_INSTANCE_CREATE_FAILED.getErrorCode(),
+ Log.getStackTraceString(e));
+ }
+ }
+ }
+ }
+ };
+ }
+ });
+ runnable = null;
} else {
// For API 15 or lower
runnable = new Runnable() {
diff --git
a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 8c31da1..ccbb45f 100755
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -31,7 +31,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.annotation.RestrictTo.Scope;
-import android.support.annotation.UiThread;
+import android.support.annotation.WorkerThread;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.util.Log;
@@ -3449,7 +3449,7 @@ public class WXBridgeManager implements Callback,
BactchExecutor {
* @param instanceId
* @return
*/
- @UiThread
+ @WorkerThread
public boolean notifyLayout(String instanceId) {
if (isSkipFrameworkInit(instanceId) || isJSFrameworkInit()) {
return mWXBridge.notifyLayout(instanceId);
@@ -3457,7 +3457,7 @@ public class WXBridgeManager implements Callback,
BactchExecutor {
return false;
}
- @UiThread
+ @WorkerThread
public void forceLayout(String instanceId) {
if (isSkipFrameworkInit(instanceId) || isJSFrameworkInit()) {
mWXBridge.forceLayout(instanceId);