give us the ability to create a background UI thread
Reviewed By: javache Differential Revision: D4928689 fbshipit-source-id: 94fa5f3f7c047ad816c7699dcc8bebf9e751b282
This commit is contained in:
parent
b4932082c7
commit
6138e20379
|
@ -47,6 +47,7 @@ public class ReactContext extends ContextWrapper {
|
|||
private @Nullable CatalystInstance mCatalystInstance;
|
||||
private @Nullable LayoutInflater mInflater;
|
||||
private @Nullable MessageQueueThread mUiMessageQueueThread;
|
||||
private @Nullable MessageQueueThread mUiBackgroundMessageQueueThread;
|
||||
private @Nullable MessageQueueThread mNativeModulesMessageQueueThread;
|
||||
private @Nullable MessageQueueThread mJSMessageQueueThread;
|
||||
private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
|
||||
|
@ -71,6 +72,7 @@ public class ReactContext extends ContextWrapper {
|
|||
|
||||
ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
|
||||
mUiMessageQueueThread = queueConfig.getUIQueueThread();
|
||||
mUiBackgroundMessageQueueThread = queueConfig.getUIBackgroundQueueThread();
|
||||
mNativeModulesMessageQueueThread = queueConfig.getNativeModulesQueueThread();
|
||||
mJSMessageQueueThread = queueConfig.getJSQueueThread();
|
||||
}
|
||||
|
@ -279,6 +281,14 @@ public class ReactContext extends ContextWrapper {
|
|||
Assertions.assertNotNull(mUiMessageQueueThread).runOnQueue(runnable);
|
||||
}
|
||||
|
||||
public void assertOnUiBackgroundQueueThread() {
|
||||
Assertions.assertNotNull(mUiBackgroundMessageQueueThread).assertIsOnThread();
|
||||
}
|
||||
|
||||
public void runOnUiBackgroundQueueThread(Runnable runnable) {
|
||||
Assertions.assertNotNull(mUiBackgroundMessageQueueThread).runOnQueue(runnable);
|
||||
}
|
||||
|
||||
public void assertOnNativeModulesQueueThread() {
|
||||
Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread();
|
||||
}
|
||||
|
@ -307,6 +317,14 @@ public class ReactContext extends ContextWrapper {
|
|||
Assertions.assertNotNull(mJSMessageQueueThread).runOnQueue(runnable);
|
||||
}
|
||||
|
||||
public void runUIBackgroundRunnable(Runnable runnable) {
|
||||
if (mUiBackgroundMessageQueueThread == null) {
|
||||
runOnNativeModulesQueueThread(runnable);
|
||||
} else {
|
||||
runOnUiBackgroundQueueThread(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the given exception to the current
|
||||
* {@link com.facebook.react.bridge.NativeModuleCallExceptionHandler} if one exists, rethrowing
|
||||
|
|
|
@ -61,7 +61,6 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
|
|||
mHandler.post(runnable);
|
||||
}
|
||||
|
||||
|
||||
@DoNotStrip
|
||||
@Override
|
||||
public <T> Future<T> callOnQueue(final Callable<T> callable) {
|
||||
|
@ -143,6 +142,8 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
|
|||
switch (spec.getThreadType()) {
|
||||
case MAIN_UI:
|
||||
return createForMainThread(spec.getName(), exceptionHandler);
|
||||
case BACKGROUND_UI:
|
||||
return startUIBackgroundThread(spec.getName(), spec.getStackSize(), exceptionHandler);
|
||||
case NEW_BACKGROUND:
|
||||
return startNewBackgroundThread(spec.getName(), spec.getStackSize(), exceptionHandler);
|
||||
default:
|
||||
|
@ -176,13 +177,27 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
|
|||
return mqt;
|
||||
}
|
||||
|
||||
public static MessageQueueThreadImpl startUIBackgroundThread(
|
||||
final String name,
|
||||
long stackSize,
|
||||
QueueThreadExceptionHandler exceptionHandler) {
|
||||
return startNewBackgroundThread(name, stackSize, exceptionHandler, true);
|
||||
}
|
||||
|
||||
public static MessageQueueThreadImpl startNewBackgroundThread(
|
||||
final String name,
|
||||
QueueThreadExceptionHandler exceptionHandler) {
|
||||
final String name,
|
||||
QueueThreadExceptionHandler exceptionHandler) {
|
||||
return startNewBackgroundThread(
|
||||
name,
|
||||
MessageQueueThreadSpec.DEFAULT_STACK_SIZE_BYTES,
|
||||
exceptionHandler);
|
||||
name,
|
||||
MessageQueueThreadSpec.DEFAULT_STACK_SIZE_BYTES,
|
||||
exceptionHandler);
|
||||
}
|
||||
|
||||
public static MessageQueueThreadImpl startNewBackgroundThread(
|
||||
final String name,
|
||||
long stackSize,
|
||||
QueueThreadExceptionHandler exceptionHandler) {
|
||||
return startNewBackgroundThread(name, stackSize, exceptionHandler, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,17 +205,20 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
|
|||
* running on it. Give it a name for easier debugging and optionally a suggested stack size.
|
||||
* When this method exits, the new MessageQueueThreadImpl is ready to receive events.
|
||||
*/
|
||||
public static MessageQueueThreadImpl startNewBackgroundThread(
|
||||
final String name,
|
||||
long stackSize,
|
||||
QueueThreadExceptionHandler exceptionHandler) {
|
||||
private static MessageQueueThreadImpl startNewBackgroundThread(
|
||||
final String name,
|
||||
long stackSize,
|
||||
QueueThreadExceptionHandler exceptionHandler,
|
||||
final boolean forUIManagerModule) {
|
||||
final SimpleSettableFuture<Looper> looperFuture = new SimpleSettableFuture<>();
|
||||
final SimpleSettableFuture<MessageQueueThread> mqtFuture = new SimpleSettableFuture<>();
|
||||
Thread bgThread = new Thread(null,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
Process.setThreadPriority(forUIManagerModule ?
|
||||
Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_MORE_FAVORABLE :
|
||||
Process.THREAD_PRIORITY_DEFAULT);
|
||||
Looper.prepare();
|
||||
|
||||
looperFuture.set(Looper.myLooper());
|
||||
|
|
|
@ -22,9 +22,14 @@ public class MessageQueueThreadSpec {
|
|||
|
||||
protected static enum ThreadType {
|
||||
MAIN_UI,
|
||||
BACKGROUND_UI,
|
||||
NEW_BACKGROUND,
|
||||
}
|
||||
|
||||
public static MessageQueueThreadSpec newUIBackgroundTreadSpec(String name) {
|
||||
return new MessageQueueThreadSpec(ThreadType.BACKGROUND_UI, name);
|
||||
}
|
||||
|
||||
public static MessageQueueThreadSpec newBackgroundThreadSpec(String name) {
|
||||
return new MessageQueueThreadSpec(ThreadType.NEW_BACKGROUND, name);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
package com.facebook.react.bridge.queue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Specifies which {@link MessageQueueThread}s must be used to run the various contexts of
|
||||
* execution within catalyst (Main UI thread, native modules, and JS). Some of these queues *may* be
|
||||
|
@ -20,6 +22,8 @@ package com.facebook.react.bridge.queue;
|
|||
*/
|
||||
public interface ReactQueueConfiguration {
|
||||
MessageQueueThread getUIQueueThread();
|
||||
@Nullable
|
||||
MessageQueueThread getUIBackgroundQueueThread();
|
||||
MessageQueueThread getNativeModulesQueueThread();
|
||||
MessageQueueThread getJSQueueThread();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
package com.facebook.react.bridge.queue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import android.os.Looper;
|
||||
|
@ -18,14 +20,17 @@ import com.facebook.react.common.MapBuilder;
|
|||
public class ReactQueueConfigurationImpl implements ReactQueueConfiguration {
|
||||
|
||||
private final MessageQueueThreadImpl mUIQueueThread;
|
||||
private final @Nullable MessageQueueThreadImpl mUIBackgroundQueueThread;
|
||||
private final MessageQueueThreadImpl mNativeModulesQueueThread;
|
||||
private final MessageQueueThreadImpl mJSQueueThread;
|
||||
|
||||
private ReactQueueConfigurationImpl(
|
||||
MessageQueueThreadImpl uiQueueThread,
|
||||
MessageQueueThreadImpl nativeModulesQueueThread,
|
||||
MessageQueueThreadImpl jsQueueThread) {
|
||||
MessageQueueThreadImpl uiQueueThread,
|
||||
@Nullable MessageQueueThreadImpl uiBackgroundQueueThread,
|
||||
MessageQueueThreadImpl nativeModulesQueueThread,
|
||||
MessageQueueThreadImpl jsQueueThread) {
|
||||
mUIQueueThread = uiQueueThread;
|
||||
mUIBackgroundQueueThread = uiBackgroundQueueThread;
|
||||
mNativeModulesQueueThread = nativeModulesQueueThread;
|
||||
mJSQueueThread = jsQueueThread;
|
||||
}
|
||||
|
@ -35,6 +40,11 @@ public class ReactQueueConfigurationImpl implements ReactQueueConfiguration {
|
|||
return mUIQueueThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MessageQueueThread getUIBackgroundQueueThread() {
|
||||
return mUIBackgroundQueueThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageQueueThread getNativeModulesQueueThread() {
|
||||
return mNativeModulesQueueThread;
|
||||
|
@ -65,7 +75,7 @@ public class ReactQueueConfigurationImpl implements ReactQueueConfiguration {
|
|||
|
||||
MessageQueueThreadSpec uiThreadSpec = MessageQueueThreadSpec.mainThreadSpec();
|
||||
MessageQueueThreadImpl uiThread =
|
||||
MessageQueueThreadImpl.create( uiThreadSpec, exceptionHandler);
|
||||
MessageQueueThreadImpl.create(uiThreadSpec, exceptionHandler);
|
||||
specsToThreads.put(uiThreadSpec, uiThread);
|
||||
|
||||
MessageQueueThreadImpl jsThread = specsToThreads.get(spec.getJSQueueThreadSpec());
|
||||
|
@ -80,6 +90,17 @@ public class ReactQueueConfigurationImpl implements ReactQueueConfiguration {
|
|||
MessageQueueThreadImpl.create(spec.getNativeModulesQueueThreadSpec(), exceptionHandler);
|
||||
}
|
||||
|
||||
return new ReactQueueConfigurationImpl(uiThread, nativeModulesThread, jsThread);
|
||||
MessageQueueThreadImpl uiBackgroundThread =
|
||||
specsToThreads.get(spec.getUIBackgroundQueueThreadSpec());
|
||||
if (uiBackgroundThread == null && spec.getUIBackgroundQueueThreadSpec() != null) {
|
||||
uiBackgroundThread =
|
||||
MessageQueueThreadImpl.create(spec.getUIBackgroundQueueThreadSpec(), exceptionHandler);
|
||||
}
|
||||
|
||||
return new ReactQueueConfigurationImpl(
|
||||
uiThread,
|
||||
uiBackgroundThread,
|
||||
nativeModulesThread,
|
||||
jsThread);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,23 @@ public class ReactQueueConfigurationSpec {
|
|||
|
||||
private static final long LEGACY_STACK_SIZE_BYTES = 2000000;
|
||||
|
||||
private final @Nullable MessageQueueThreadSpec mUIBackgroundQueueThreadSpec;
|
||||
private final MessageQueueThreadSpec mNativeModulesQueueThreadSpec;
|
||||
private final MessageQueueThreadSpec mJSQueueThreadSpec;
|
||||
|
||||
private ReactQueueConfigurationSpec(
|
||||
MessageQueueThreadSpec nativeModulesQueueThreadSpec,
|
||||
MessageQueueThreadSpec jsQueueThreadSpec) {
|
||||
@Nullable MessageQueueThreadSpec uiBackgroundQueueThreadSpec,
|
||||
MessageQueueThreadSpec nativeModulesQueueThreadSpec,
|
||||
MessageQueueThreadSpec jsQueueThreadSpec) {
|
||||
mUIBackgroundQueueThreadSpec = uiBackgroundQueueThreadSpec;
|
||||
mNativeModulesQueueThreadSpec = nativeModulesQueueThreadSpec;
|
||||
mJSQueueThreadSpec = jsQueueThreadSpec;
|
||||
}
|
||||
|
||||
public @Nullable MessageQueueThreadSpec getUIBackgroundQueueThreadSpec() {
|
||||
return mUIBackgroundQueueThreadSpec;
|
||||
}
|
||||
|
||||
public MessageQueueThreadSpec getNativeModulesQueueThreadSpec() {
|
||||
return mNativeModulesQueueThreadSpec;
|
||||
}
|
||||
|
@ -57,15 +64,36 @@ public class ReactQueueConfigurationSpec {
|
|||
.build();
|
||||
}
|
||||
|
||||
public static ReactQueueConfigurationSpec createWithSeparateUIBackgroundThread() {
|
||||
MessageQueueThreadSpec spec = Build.VERSION.SDK_INT < 21 ?
|
||||
MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules", LEGACY_STACK_SIZE_BYTES) :
|
||||
MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules");
|
||||
return builder()
|
||||
.setJSQueueThreadSpec(MessageQueueThreadSpec.newBackgroundThreadSpec("js"))
|
||||
.setNativeModulesQueueThreadSpec(spec)
|
||||
.setUIBackgroundQueueThreadSpec(
|
||||
MessageQueueThreadSpec.newUIBackgroundTreadSpec("ui_background"))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private @Nullable MessageQueueThreadSpec mUIBackgroundQueueSpec;
|
||||
private @Nullable MessageQueueThreadSpec mNativeModulesQueueSpec;
|
||||
private @Nullable MessageQueueThreadSpec mJSQueueSpec;
|
||||
|
||||
public Builder setUIBackgroundQueueThreadSpec(MessageQueueThreadSpec spec) {
|
||||
Assertions.assertCondition(
|
||||
mUIBackgroundQueueSpec == null,
|
||||
"Setting UI background queue multiple times!");
|
||||
mUIBackgroundQueueSpec = spec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setNativeModulesQueueThreadSpec(MessageQueueThreadSpec spec) {
|
||||
Assertions.assertCondition(
|
||||
mNativeModulesQueueSpec == null,
|
||||
"Setting native modules queue spec multiple times!");
|
||||
mNativeModulesQueueSpec == null,
|
||||
"Setting native modules queue spec multiple times!");
|
||||
mNativeModulesQueueSpec = spec;
|
||||
return this;
|
||||
}
|
||||
|
@ -78,8 +106,9 @@ public class ReactQueueConfigurationSpec {
|
|||
|
||||
public ReactQueueConfigurationSpec build() {
|
||||
return new ReactQueueConfigurationSpec(
|
||||
Assertions.assertNotNull(mNativeModulesQueueSpec),
|
||||
Assertions.assertNotNull(mJSQueueSpec));
|
||||
mUIBackgroundQueueSpec,
|
||||
Assertions.assertNotNull(mNativeModulesQueueSpec),
|
||||
Assertions.assertNotNull(mJSQueueSpec));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ import java.lang.reflect.Method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.BaseJavaModule;
|
||||
|
|
|
@ -31,10 +31,8 @@ import com.facebook.react.bridge.ReactMarker;
|
|||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.systrace.Systrace;
|
||||
|
@ -212,7 +210,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
new SizeMonitoringFrameLayout.OnSizeChangedListener() {
|
||||
@Override
|
||||
public void onSizeChanged(final int width, final int height, int oldW, int oldH) {
|
||||
reactApplicationContext.runOnNativeModulesQueueThread(
|
||||
reactApplicationContext.runUIBackgroundRunnable(
|
||||
new GuardedRunnable(reactApplicationContext) {
|
||||
@Override
|
||||
public void runGuarded() {
|
||||
|
|
|
@ -306,7 +306,7 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe
|
|||
if (getChildCount() > 0) {
|
||||
final int viewTag = getChildAt(0).getId();
|
||||
ReactContext reactContext = (ReactContext) getContext();
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
reactContext.runUIBackgroundRunnable(
|
||||
new GuardedRunnable(reactContext) {
|
||||
@Override
|
||||
public void runGuarded() {
|
||||
|
|
Loading…
Reference in New Issue