launch conversion from ASyncTask to Thread
Reviewed By: achen1 Differential Revision: D4900998 fbshipit-source-id: af2283525b4e9856d7ff3466096226c4c1209f6b
This commit is contained in:
Родитель
3fda6a9a2b
Коммит
3e866e0380
|
@ -22,9 +22,7 @@ import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Process;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
|
@ -130,7 +128,6 @@ public class ReactInstanceManager {
|
||||||
|
|
||||||
private volatile LifecycleState mLifecycleState;
|
private volatile LifecycleState mLifecycleState;
|
||||||
private @Nullable @ThreadConfined(UI) ReactContextInitParams mPendingReactContextInitParams;
|
private @Nullable @ThreadConfined(UI) ReactContextInitParams mPendingReactContextInitParams;
|
||||||
private @Nullable @ThreadConfined(UI) ReactContextInitAsyncTask mReactContextInitAsyncTask;
|
|
||||||
private @Nullable @ThreadConfined(UI) Thread mCreateReactContextThread;
|
private @Nullable @ThreadConfined(UI) Thread mCreateReactContextThread;
|
||||||
|
|
||||||
/* accessed from any thread */
|
/* accessed from any thread */
|
||||||
|
@ -153,7 +150,7 @@ public class ReactInstanceManager {
|
||||||
private final JSCConfig mJSCConfig;
|
private final JSCConfig mJSCConfig;
|
||||||
private final boolean mLazyNativeModulesEnabled;
|
private final boolean mLazyNativeModulesEnabled;
|
||||||
private final boolean mLazyViewManagersEnabled;
|
private final boolean mLazyViewManagersEnabled;
|
||||||
private final boolean mUseStartupThread;
|
private final boolean mSetupReactContextInBackgroundEnabled;
|
||||||
|
|
||||||
private final ReactInstanceDevCommandsHandler mDevInterface =
|
private final ReactInstanceDevCommandsHandler mDevInterface =
|
||||||
new ReactInstanceDevCommandsHandler() {
|
new ReactInstanceDevCommandsHandler() {
|
||||||
|
@ -202,105 +199,6 @@ public class ReactInstanceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Task class responsible for (re)creating react context in the background. These tasks can only
|
|
||||||
* be executing one at time, see {@link #recreateReactContextInBackground()}.
|
|
||||||
*/
|
|
||||||
private final class ReactContextInitAsyncTask extends
|
|
||||||
AsyncTask<ReactContextInitParams, Void, Result<ReactApplicationContext>> {
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
if (mCurrentReactContext != null) {
|
|
||||||
tearDownReactContext(mCurrentReactContext);
|
|
||||||
mCurrentReactContext = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Result<ReactApplicationContext> doInBackground(ReactContextInitParams... params) {
|
|
||||||
// TODO(t11687218): Look over all threading
|
|
||||||
// Default priority is Process.THREAD_PRIORITY_BACKGROUND which means we'll be put in a cgroup
|
|
||||||
// that only has access to a small fraction of CPU time. The priority will be reset after
|
|
||||||
// this task finishes: https://android.googlesource.com/platform/frameworks/base/+/d630f105e8bc0021541aacb4dc6498a49048ecea/core/java/android/os/AsyncTask.java#256
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
|
||||||
|
|
||||||
Assertions.assertCondition(params != null && params.length > 0 && params[0] != null);
|
|
||||||
try {
|
|
||||||
JavaScriptExecutor jsExecutor = params[0].getJsExecutorFactory().create();
|
|
||||||
ReactApplicationContext reactApplicationContext =
|
|
||||||
createReactContext(jsExecutor, params[0].getJsBundleLoader());
|
|
||||||
ReactMarker.logMarker(PRE_SETUP_REACT_CONTEXT_START);
|
|
||||||
return Result.of(reactApplicationContext);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Pass exception to onPostExecute() so it can be handled on the main thread
|
|
||||||
return Result.of(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Result<ReactApplicationContext> result) {
|
|
||||||
try {
|
|
||||||
setupReactContext(result.get());
|
|
||||||
} catch (Exception e) {
|
|
||||||
mDevSupportManager.handleException(e);
|
|
||||||
} finally {
|
|
||||||
mReactContextInitAsyncTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle enqueued request to re-initialize react context.
|
|
||||||
if (mPendingReactContextInitParams != null) {
|
|
||||||
recreateReactContextInBackground(
|
|
||||||
mPendingReactContextInitParams.getJsExecutorFactory(),
|
|
||||||
mPendingReactContextInitParams.getJsBundleLoader());
|
|
||||||
mPendingReactContextInitParams = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCancelled(Result<ReactApplicationContext> reactApplicationContextResult) {
|
|
||||||
try {
|
|
||||||
mMemoryPressureRouter.destroy(reactApplicationContextResult.get());
|
|
||||||
} catch (Exception e) {
|
|
||||||
FLog.w(ReactConstants.TAG, "Caught exception after cancelling react context init", e);
|
|
||||||
} finally {
|
|
||||||
mReactContextInitAsyncTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Result<T> {
|
|
||||||
@Nullable private final T mResult;
|
|
||||||
@Nullable private final Exception mException;
|
|
||||||
|
|
||||||
public static <T, U extends T> Result<T> of(U result) {
|
|
||||||
return new Result<T>(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> of(Exception exception) {
|
|
||||||
return new Result<>(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result(T result) {
|
|
||||||
mException = null;
|
|
||||||
mResult = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result(Exception exception) {
|
|
||||||
mException = exception;
|
|
||||||
mResult = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get() throws Exception {
|
|
||||||
if (mException != null) {
|
|
||||||
throw mException;
|
|
||||||
}
|
|
||||||
|
|
||||||
Assertions.assertNotNull(mResult);
|
|
||||||
|
|
||||||
return mResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a builder that is capable of creating an instance of {@link ReactInstanceManager}.
|
* Creates a builder that is capable of creating an instance of {@link ReactInstanceManager}.
|
||||||
*/
|
*/
|
||||||
|
@ -324,7 +222,7 @@ public class ReactInstanceManager {
|
||||||
@Nullable RedBoxHandler redBoxHandler,
|
@Nullable RedBoxHandler redBoxHandler,
|
||||||
boolean lazyNativeModulesEnabled,
|
boolean lazyNativeModulesEnabled,
|
||||||
boolean lazyViewManagersEnabled,
|
boolean lazyViewManagersEnabled,
|
||||||
boolean useStartupThread) {
|
boolean setupReactContextInBackgroundEnabled) {
|
||||||
|
|
||||||
initializeSoLoaderIfNecessary(applicationContext);
|
initializeSoLoaderIfNecessary(applicationContext);
|
||||||
|
|
||||||
|
@ -353,7 +251,7 @@ public class ReactInstanceManager {
|
||||||
mJSCConfig = jscConfig;
|
mJSCConfig = jscConfig;
|
||||||
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
|
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
|
||||||
mLazyViewManagersEnabled = lazyViewManagersEnabled;
|
mLazyViewManagersEnabled = lazyViewManagersEnabled;
|
||||||
mUseStartupThread = useStartupThread;
|
mSetupReactContextInBackgroundEnabled = setupReactContextInBackgroundEnabled;
|
||||||
|
|
||||||
// Instantiate ReactChoreographer in UI thread.
|
// Instantiate ReactChoreographer in UI thread.
|
||||||
ReactChoreographer.initialize();
|
ReactChoreographer.initialize();
|
||||||
|
@ -632,10 +530,6 @@ public class ReactInstanceManager {
|
||||||
|
|
||||||
moveToBeforeCreateLifecycleState();
|
moveToBeforeCreateLifecycleState();
|
||||||
|
|
||||||
if (mReactContextInitAsyncTask != null) {
|
|
||||||
mReactContextInitAsyncTask.cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCreateReactContextThread != null) {
|
if (mCreateReactContextThread != null) {
|
||||||
mCreateReactContextThread.interrupt();
|
mCreateReactContextThread.interrupt();
|
||||||
mCreateReactContextThread = null;
|
mCreateReactContextThread = null;
|
||||||
|
@ -728,9 +622,7 @@ public class ReactInstanceManager {
|
||||||
|
|
||||||
// If react context is being created in the background, JS application will be started
|
// If react context is being created in the background, JS application will be started
|
||||||
// automatically when creation completes, as root view is part of the attached root view list.
|
// automatically when creation completes, as root view is part of the attached root view list.
|
||||||
if (mReactContextInitAsyncTask == null &&
|
if (mCreateReactContextThread == null && mCurrentReactContext != null) {
|
||||||
mCreateReactContextThread == null &&
|
|
||||||
mCurrentReactContext != null) {
|
|
||||||
attachMeasuredRootViewToInstance(rootView, mCurrentReactContext.getCatalystInstance());
|
attachMeasuredRootViewToInstance(rootView, mCurrentReactContext.getCatalystInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,23 +723,11 @@ public class ReactInstanceManager {
|
||||||
final ReactContextInitParams initParams = new ReactContextInitParams(
|
final ReactContextInitParams initParams = new ReactContextInitParams(
|
||||||
jsExecutorFactory,
|
jsExecutorFactory,
|
||||||
jsBundleLoader);
|
jsBundleLoader);
|
||||||
if (mUseStartupThread) {
|
|
||||||
if (mCreateReactContextThread == null) {
|
if (mCreateReactContextThread == null) {
|
||||||
runCreateReactContextOnNewThread(initParams);
|
runCreateReactContextOnNewThread(initParams);
|
||||||
} else {
|
} else {
|
||||||
mPendingReactContextInitParams = initParams;
|
mPendingReactContextInitParams = initParams;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (mReactContextInitAsyncTask == null) {
|
|
||||||
// No background task to create react context is currently running, create and execute one.
|
|
||||||
mReactContextInitAsyncTask = new ReactContextInitAsyncTask();
|
|
||||||
mReactContextInitAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, initParams);
|
|
||||||
} else {
|
|
||||||
// Background task is currently running, queue up most recent init params to recreate
|
|
||||||
// context once task completes.
|
|
||||||
mPendingReactContextInitParams = initParams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(UI)
|
@ThreadConfined(UI)
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class ReactInstanceManagerBuilder {
|
||||||
protected @Nullable RedBoxHandler mRedBoxHandler;
|
protected @Nullable RedBoxHandler mRedBoxHandler;
|
||||||
protected boolean mLazyNativeModulesEnabled;
|
protected boolean mLazyNativeModulesEnabled;
|
||||||
protected boolean mLazyViewManagersEnabled;
|
protected boolean mLazyViewManagersEnabled;
|
||||||
protected boolean mUseStartupThread;
|
protected boolean mSetupReactContextInBackground;
|
||||||
|
|
||||||
/* package protected */ ReactInstanceManagerBuilder() {
|
/* package protected */ ReactInstanceManagerBuilder() {
|
||||||
}
|
}
|
||||||
|
@ -187,8 +187,9 @@ public class ReactInstanceManagerBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReactInstanceManagerBuilder setUseStartupThread(boolean useStartupThread) {
|
public ReactInstanceManagerBuilder setSetupReactContextInBackgroundEnabled(
|
||||||
mUseStartupThread = useStartupThread;
|
boolean setupReactContextInBackground) {
|
||||||
|
mSetupReactContextInBackground = setupReactContextInBackground;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +238,6 @@ public class ReactInstanceManagerBuilder {
|
||||||
mRedBoxHandler,
|
mRedBoxHandler,
|
||||||
mLazyNativeModulesEnabled,
|
mLazyNativeModulesEnabled,
|
||||||
mLazyViewManagersEnabled,
|
mLazyViewManagersEnabled,
|
||||||
mUseStartupThread);
|
mSetupReactContextInBackground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче