mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-01 06:22:39 +08:00
support api 15 (use Handler-backed ui driven).
Summary: Android API 15 still have 1.5~2.0% distribution (refer: [Dashboard - Android Developer](https://developer.android.com/ndk/guides/standalone_toolchain.html#creating_the_toolchain)). React Native is a good tec but many companies cannot endure loose their consumer. [Choreographer](https://developer.android.com/reference/android/view/Choreographer.html) triggered UI operation is the only reason that React Native Android sdk use minSdkVersion 16, so we can use a backward solution **only in API 15**: [Handler](https://developer.android.com/reference/android/os/Handler.html). In this PR, the biggest change is : - Make core operation of ReactChoreographer to an interface: ReactUIDriver; - Impl ReactUIDriver by Handler => UIDriverHandlerImpl, refactor ReactChoreographer to UIDriverChoreographerImpl; - Let UIDriverFactory to choose which one impl would be in use. (Only use handler in api 15). Closes https://github.com/facebook/react-native/pull/12396 Reviewed By: AaaChiuuu Differential Revision: D4588399 Pulled By: astreet fbshipit-source-id: 76408e53664314dd926e6a553cde6bafbd37779e
This commit is contained in:
committed by
Facebook Github Bot
parent
8b01508410
commit
20ad2b3fbb
@@ -13,8 +13,6 @@ import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import android.os.Build;
|
||||
import android.view.Choreographer;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
@@ -24,6 +22,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.ChoreographerCompat;
|
||||
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
||||
|
||||
/**
|
||||
@@ -60,10 +59,9 @@ public class AnimationsDebugModule extends ReactContextBaseJavaModule {
|
||||
if (mFrameCallback != null) {
|
||||
throw new JSApplicationCausedNativeException("Already recording FPS!");
|
||||
}
|
||||
checkAPILevel();
|
||||
|
||||
mFrameCallback = new FpsDebugFrameCallback(
|
||||
Choreographer.getInstance(),
|
||||
ChoreographerCompat.getInstance(),
|
||||
getReactApplicationContext());
|
||||
mFrameCallback.startAndRecordFpsAtEachFrame();
|
||||
}
|
||||
@@ -78,7 +76,6 @@ public class AnimationsDebugModule extends ReactContextBaseJavaModule {
|
||||
if (mFrameCallback == null) {
|
||||
return;
|
||||
}
|
||||
checkAPILevel();
|
||||
|
||||
mFrameCallback.stop();
|
||||
|
||||
@@ -116,11 +113,4 @@ public class AnimationsDebugModule extends ReactContextBaseJavaModule {
|
||||
mFrameCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAPILevel() {
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
throw new JSApplicationCausedNativeException(
|
||||
"Animation debugging is not supported in API <16");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ android_library(
|
||||
react_native_target("java/com/facebook/react/bridge:bridge"),
|
||||
react_native_target("java/com/facebook/react/common:common"),
|
||||
react_native_target("java/com/facebook/react/module/annotations:annotations"),
|
||||
react_native_target('java/com/facebook/react/modules/core:core'),
|
||||
react_native_target("java/com/facebook/react/modules/debug:interfaces"),
|
||||
react_native_target("java/com/facebook/react/uimanager:uimanager"),
|
||||
],
|
||||
|
||||
@@ -9,11 +9,10 @@
|
||||
|
||||
package com.facebook.react.modules.debug;
|
||||
|
||||
import android.view.Choreographer;
|
||||
|
||||
import com.facebook.react.bridge.ReactBridge;
|
||||
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
|
||||
import com.facebook.react.common.LongArray;
|
||||
import com.facebook.react.modules.core.ChoreographerCompat;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
|
||||
@@ -22,7 +21,7 @@ import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugL
|
||||
* to calculate whether JS was able to update the UI during a given frame. After being installed
|
||||
* on a {@link ReactBridge} and a {@link UIManagerModule},
|
||||
* {@link #getDidJSHitFrameAndCleanup} should be called once per frame via a
|
||||
* {@link Choreographer.FrameCallback}.
|
||||
* {@link ChoreographerCompat.FrameCallback}.
|
||||
*/
|
||||
public class DidJSUpdateUiDuringFrameDetector implements NotThreadSafeBridgeIdleDebugListener,
|
||||
NotThreadSafeViewHierarchyUpdateDebugListener {
|
||||
@@ -56,7 +55,7 @@ public class DidJSUpdateUiDuringFrameDetector implements NotThreadSafeBridgeIdle
|
||||
}
|
||||
|
||||
/**
|
||||
* Designed to be called from a {@link Choreographer.FrameCallback#doFrame} call.
|
||||
* Designed to be called from a {@link ChoreographerCompat.FrameCallback#doFrame} call.
|
||||
*
|
||||
* There are two 'success' cases that will cause {@link #getDidJSHitFrameAndCleanup} to
|
||||
* return true for a given frame:
|
||||
|
||||
@@ -14,10 +14,8 @@ import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.view.Choreographer;
|
||||
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.core.ChoreographerCompat;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
|
||||
@@ -30,11 +28,8 @@ import com.facebook.infer.annotation.Assertions;
|
||||
* Also records the JS FPS, i.e. the frames per second with which either JS updated the UI or was
|
||||
* idle and not trying to update the UI. This is different from the FPS above since JS rendering is
|
||||
* async.
|
||||
*
|
||||
* TargetApi 16 for use of Choreographer.
|
||||
*/
|
||||
@TargetApi(16)
|
||||
public class FpsDebugFrameCallback implements Choreographer.FrameCallback {
|
||||
public class FpsDebugFrameCallback extends ChoreographerCompat.FrameCallback {
|
||||
|
||||
public static class FpsInfo {
|
||||
|
||||
@@ -66,7 +61,7 @@ public class FpsDebugFrameCallback implements Choreographer.FrameCallback {
|
||||
|
||||
private static final double EXPECTED_FRAME_TIME = 16.9;
|
||||
|
||||
private final Choreographer mChoreographer;
|
||||
private final ChoreographerCompat mChoreographer;
|
||||
private final ReactContext mReactContext;
|
||||
private final UIManagerModule mUIManagerModule;
|
||||
private final DidJSUpdateUiDuringFrameDetector mDidJSUpdateUiDuringFrameDetector;
|
||||
@@ -81,7 +76,7 @@ public class FpsDebugFrameCallback implements Choreographer.FrameCallback {
|
||||
private boolean mIsRecordingFpsInfoAtEachFrame = false;
|
||||
private @Nullable TreeMap<Long, FpsInfo> mTimeToFps;
|
||||
|
||||
public FpsDebugFrameCallback(Choreographer choreographer, ReactContext reactContext) {
|
||||
public FpsDebugFrameCallback(ChoreographerCompat choreographer, ReactContext reactContext) {
|
||||
mChoreographer = choreographer;
|
||||
mReactContext = reactContext;
|
||||
mUIManagerModule = reactContext.getNativeModule(UIManagerModule.class);
|
||||
|
||||
Reference in New Issue
Block a user