mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement BackgroundExecutor for layouts
Summary: As a followup to D22743723 (https://github.com/facebook/react-native/commit/d53fc8a3cd44c7ec7e6eade985daf3d4feb2d736) on the iOS side, I implement a BackgroundExecutor that can be used from C++ to schedule layouts on their own thread, off the JS and UI thread. This is a potential perf improvement that we will experiment with. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D22826795 fbshipit-source-id: 899bd67fe1b86f52910951e9536b59a1414a304c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a1ed73dd64
commit
949dedca9f
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@DoNotStrip
|
||||
public class BackgroundExecutor {
|
||||
private static final String TAG = "FabricBackgroundExecutor";
|
||||
private final ExecutorService mExecutorService;
|
||||
|
||||
@DoNotStrip
|
||||
private BackgroundExecutor() {
|
||||
mExecutorService = Executors.newFixedThreadPool(1);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
private void queueRunnable(Runnable runnable) {
|
||||
// Very rarely, an NPE is hit here - probably has to do with deallocation
|
||||
// race conditions and the JNI.
|
||||
// It's not clear yet which of these is most prevalent, or if either is a concern.
|
||||
// If we don't find these logs in production then we can probably safely remove the logging,
|
||||
// but it's also cheap to leave it here.
|
||||
|
||||
if (runnable == null) {
|
||||
ReactSoftException.logSoftException(TAG, new ReactNoCrashSoftException("runnable is null"));
|
||||
return;
|
||||
}
|
||||
|
||||
final ExecutorService executorService = mExecutorService;
|
||||
if (executorService == null) {
|
||||
ReactSoftException.logSoftException(
|
||||
TAG, new ReactNoCrashSoftException("executorService is null"));
|
||||
return;
|
||||
}
|
||||
|
||||
executorService.execute(runnable);
|
||||
}
|
||||
}
|
||||
@@ -278,6 +278,12 @@ void Binding::installFabricUIManager(
|
||||
toolbox.synchronousEventBeatFactory = synchronousBeatFactory;
|
||||
toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory;
|
||||
|
||||
if (reactNativeConfig_->getBool(
|
||||
"react_fabric:enable_background_executor_android")) {
|
||||
backgroundExecutor_ = std::make_unique<JBackgroundExecutor>();
|
||||
toolbox.backgroundExecutor = backgroundExecutor_->get();
|
||||
}
|
||||
|
||||
if (enableLayoutAnimations) {
|
||||
animationDriver_ = std::make_shared<LayoutAnimationDriver>(this);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <mutex>
|
||||
#include "ComponentFactoryDelegate.h"
|
||||
#include "EventBeatManager.h"
|
||||
#include "JBackgroundExecutor.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -115,6 +116,7 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
virtual void onAllAnimationsComplete() override;
|
||||
LayoutAnimationDriver *getAnimationDriver();
|
||||
std::shared_ptr<LayoutAnimationDriver> animationDriver_;
|
||||
std::unique_ptr<JBackgroundExecutor> backgroundExecutor_;
|
||||
|
||||
std::shared_ptr<Scheduler> scheduler_;
|
||||
std::mutex schedulerMutex_;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/jni/JNativeRunnable.h>
|
||||
|
||||
#include "JBackgroundExecutor.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
using facebook::react::JNativeRunnable;
|
||||
using facebook::react::Runnable;
|
||||
|
||||
BackgroundExecutor JBackgroundExecutor::get() {
|
||||
auto self = JBackgroundExecutor::create();
|
||||
|
||||
return [self](std::function<void()> &&runnable) {
|
||||
static auto method =
|
||||
findClassStatic(JBackgroundExecutor::JBackgroundExecutorJavaDescriptor)
|
||||
->getMethod<void(Runnable::javaobject)>("queueRunnable");
|
||||
|
||||
auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
|
||||
method(self, static_ref_cast<Runnable>(jrunnable).get());
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/uimanager/primitives.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
class JBackgroundExecutor : public JavaClass<JBackgroundExecutor> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/facebook/react/bridge/BackgroundExecutor;";
|
||||
|
||||
constexpr static auto JBackgroundExecutorJavaDescriptor =
|
||||
"com/facebook/react/bridge/BackgroundExecutor";
|
||||
|
||||
static global_ref<javaobject> create() {
|
||||
return make_global(newInstance());
|
||||
}
|
||||
|
||||
BackgroundExecutor get();
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
Reference in New Issue
Block a user