下面列出了com.facebook.react.bridge.JavaScriptExecutorFactory#com.facebook.react.common.ReactConstants 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void copyExif(Context context, Uri oldImage, File newFile) throws IOException {
File oldFile = getFileFromUri(context, oldImage);
if (oldFile == null) {
FLog.w(ReactConstants.TAG, "Couldn't get real path for uri: " + oldImage);
return;
}
ExifInterface oldExif = new ExifInterface(oldFile.getAbsolutePath());
ExifInterface newExif = new ExifInterface(newFile.getAbsolutePath());
for (String attribute : EXIF_ATTRIBUTES) {
String value = oldExif.getAttribute(attribute);
if (value != null) {
newExif.setAttribute(attribute, value);
}
}
newExif.saveAttributes();
}
private static void ashmemInfo(@Nonnull String stateLabel) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
BitmapCounter counter = BitmapCounterProvider.get();
FLog.d(
ReactConstants.TAG,
String.format(
Locale.ROOT,
"ImageFilterKit: bitmap pool %s - %d/%d images, %d/%d MB",
stateLabel,
counter.getCount(),
counter.getMaxCount(),
counter.getSize() / 1024 / 1024,
counter.getMaxSize() / 1024 / 1024
)
);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
if (super.onInterceptTouchEvent(ev)) {
NativeGestureUtil.notifyNativeGestureStarted(this, ev);
return true;
}
} catch (IllegalArgumentException e) {
// Log and ignore the error. This seems to be a bug in the android SDK and
// this is the commonly accepted workaround.
// https://tinyurl.com/mw6qkod (Stack Overflow)
Log.w(ReactConstants.TAG, "Error intercepting touch event.", e);
}
return false;
}
@Override
protected Void doInBackground(String... clipBoardString) {
try {
String sendClipBoardUrl =
Uri.parse(mDevSupportManager.getSourceUrl()).buildUpon()
.path("/copy-to-clipboard")
.query(null)
.build()
.toString();
for (String string: clipBoardString) {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(null, string);
Request request = new Request.Builder().url(sendClipBoardUrl).post(body).build();
client.newCall(request).execute();
}
} catch (Exception e) {
FLog.e(ReactConstants.TAG, "Could not copy to the host clipboard", e);
}
return null;
}
public void linkBridge() {
if (messagingEnabled) {
if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// See isNative in lodash
String testPostMessageNative = "String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')";
evaluateJavascript(testPostMessageNative, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
if (value.equals("true")) {
FLog.w(ReactConstants.TAG, "Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
}
}
});
}
evaluateJavascriptWithFallback("(" +
"window.originalPostMessage = window.postMessage," +
"window.postMessage = function(data) {" +
BRIDGE_NAME + ".postMessage(String(data));" +
"}" +
")");
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!mScrollEnabled) {
return false;
}
try {
if (super.onInterceptTouchEvent(ev)) {
NativeGestureUtil.notifyNativeGestureStarted(this, ev);
return true;
}
} catch (IllegalArgumentException e) {
// Log and ignore the error. This seems to be a bug in the android SDK and
// this is the commonly accepted workaround.
// https://tinyurl.com/mw6qkod (Stack Overflow)
Log.w(ReactConstants.TAG, "Error intercepting touch event.", e);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!mScrollEnabled) {
return false;
}
try {
if (super.onInterceptTouchEvent(ev)) {
NativeGestureUtil.notifyNativeGestureStarted(this, ev);
ReactScrollViewHelper.emitScrollBeginDragEvent(this);
mDragging = true;
enableFpsListener();
return true;
}
} catch (IllegalArgumentException e) {
// Log and ignore the error. This seems to be a bug in the android SDK and
// this is the commonly accepted workaround.
// https://tinyurl.com/mw6qkod (Stack Overflow)
Log.w(ReactConstants.TAG, "Error intercepting touch event.", e);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!mScrollEnabled) {
return false;
}
try {
if (super.onInterceptTouchEvent(ev)) {
NativeGestureUtil.notifyNativeGestureStarted(this, ev);
ReactScrollViewHelper.emitScrollBeginDragEvent(this);
mDragging = true;
enableFpsListener();
return true;
}
} catch (IllegalArgumentException e) {
// Log and ignore the error. This seems to be a bug in the android SDK and
// this is the commonly accepted workaround.
// https://tinyurl.com/mw6qkod (Stack Overflow)
Log.w(ReactConstants.TAG, "Error intercepting touch event.", e);
}
return false;
}
@Override
protected Void doInBackground(StackFrame... stackFrames) {
try {
String openStackFrameUrl =
Uri.parse(mDevSupportManager.getSourceUrl()).buildUpon()
.path("/open-stack-frame")
.query(null)
.build()
.toString();
OkHttpClient client = new OkHttpClient();
for (StackFrame frame: stackFrames) {
String payload = stackFrameToJson(frame).toString();
RequestBody body = RequestBody.create(JSON, payload);
Request request = new Request.Builder().url(openStackFrameUrl).post(body).build();
client.newCall(request).execute();
}
} catch (Exception e) {
FLog.e(ReactConstants.TAG, "Could not open stack frame", e);
}
return null;
}
/**
* Returns the input stream for a file given by its contentUri. Returns null if the file has not
* been found or if an error as occurred.
*/
public static @Nullable InputStream getFileInputStream(
Context context,
String fileContentUriStr) {
try {
Uri fileContentUri = Uri.parse(fileContentUriStr);
if (fileContentUri.getScheme().startsWith("http")) {
return getDownloadFileInputStream(context, fileContentUri);
}
return context.getContentResolver().openInputStream(fileContentUri);
} catch (Exception e) {
FLog.e(
ReactConstants.TAG,
"Could not retrieve file for contentUri " + fileContentUriStr,
e);
return null;
}
}
@Override
public void initialize() {
super.initialize();
getReactApplicationContext().addLifecycleEventListener(this);
if (!hasBeenInitialized()) {
if (mConfig == null) {
mConfig = getDefaultConfig(getReactApplicationContext());
}
Context context = getReactApplicationContext().getApplicationContext();
Fresco.initialize(context, mConfig);
sHasBeenInitialized = true;
} else if (mConfig != null) {
FLog.w(
ReactConstants.TAG,
"Fresco has already been initialized with a different config. "
+ "The new Fresco configuration will be ignored!");
}
mConfig = null;
}
private static void copyExif(Context context, Uri oldImage, File newFile) throws IOException {
File oldFile = getFileFromUri(context, oldImage);
if (oldFile == null) {
FLog.w(ReactConstants.TAG, "Couldn't get real path for uri: " + oldImage);
return;
}
ExifInterface oldExif = new ExifInterface(oldFile.getAbsolutePath());
ExifInterface newExif = new ExifInterface(newFile.getAbsolutePath());
for (String attribute : EXIF_ATTRIBUTES) {
String value = oldExif.getAttribute(attribute);
if (value != null) {
newExif.setAttribute(attribute, value);
}
}
newExif.saveAttributes();
}
@ReactMethod
public void close(int code, String reason, int id) {
WebSocket client = mWebSocketConnections.get(id);
if (client == null) {
// WebSocket is already closed
// Don't do anything, mirror the behaviour on web
return;
}
try {
client.close(code, reason);
mWebSocketConnections.remove(id);
mContentHandlers.remove(id);
} catch (Exception e) {
FLog.e(
ReactConstants.TAG,
"Could not close WebSocket connection for id " + id,
e);
}
}
/**
* Invoked when native view that corresponds to a root node, or acts as a root view (ie. Modals)
* has its size changed.
*/
public void updateNodeSize(
int nodeViewTag,
int newWidth,
int newHeight) {
ReactShadowNode cssNode = mShadowNodeRegistry.getNode(nodeViewTag);
if (cssNode == null) {
FLog.w(
ReactConstants.TAG,
"Tried to update size of non-existent tag: " + nodeViewTag);
return;
}
cssNode.setStyleWidth(newWidth);
cssNode.setStyleHeight(newHeight);
dispatchViewUpdatesIfNeeded();
}
@ReactMethod
public void setHidden(final boolean hidden) {
final Activity activity = getCurrentActivity();
if (activity == null) {
FLog.w(ReactConstants.TAG, "StatusBarModule: Ignored status bar change, current activity is null.");
return;
}
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
public void run() {
if (hidden) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
});
}
@ReactMethod
public void setStyle(@Nullable final String style) {
final Activity activity = getCurrentActivity();
if (activity == null) {
FLog.w(ReactConstants.TAG, "StatusBarModule: Ignored status bar change, current activity is null.");
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
UiThreadUtil.runOnUiThread(
new Runnable() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void run() {
View decorView = activity.getWindow().getDecorView();
decorView.setSystemUiVisibility(
"dark-content".equals(style) ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0);
}
}
);
}
}
/**
* Clears the database.
*/
@ReactMethod
public void clear(final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
protected void doInBackgroundGuarded(Void... params) {
if (!mReactDatabaseSupplier.ensureDatabase()) {
callback.invoke(AsyncStorageErrorUtil.getDBError(null));
return;
}
try {
mReactDatabaseSupplier.clear();
callback.invoke();
} catch (Exception e) {
FLog.w(ReactConstants.TAG, e.getMessage(), e);
callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()));
}
}
}.executeOnExecutor(executor);
}
@Override
public void runJSBundle() {
Log.d(ReactConstants.TAG, "CatalystInstanceImpl.runJSBundle()");
Assertions.assertCondition(!mJSBundleHasLoaded, "JS bundle was already loaded!");
// incrementPendingJSCalls();
mJSBundleLoader.loadScript(CatalystInstanceImpl.this);
synchronized (mJSCallsPendingInitLock) {
// Loading the bundle is queued on the JS thread, but may not have
// run yet. It's safe to set this here, though, since any work it
// gates will be queued on the JS thread behind the load.
mAcceptCalls = true;
for (PendingJSCall function : mJSCallsPendingInit) {
function.call(this);
}
mJSCallsPendingInit.clear();
mJSBundleHasLoaded = true;
}
// This is registered after JS starts since it makes a JS call
Systrace.registerListener(mTraceListener);
}
public void callFunction(PendingJSCall function) {
if (mDestroyed) {
final String call = function.toString();
FLog.w(ReactConstants.TAG, "Calling JS function after bridge has been destroyed: " + call);
return;
}
if (!mAcceptCalls) {
// Most of the time the instance is initialized and we don't need to acquire the lock
synchronized (mJSCallsPendingInitLock) {
if (!mAcceptCalls) {
mJSCallsPendingInit.add(function);
return;
}
}
}
function.call(this);
}
public int resolveRootTagFromReactTag(int reactTag) {
if (mShadowNodeRegistry.isRootNode(reactTag)) {
return reactTag;
}
ReactShadowNode node = resolveShadowNode(reactTag);
int rootTag = 0;
if (node != null) {
rootTag = node.getRootTag();
} else {
FLog.w(
ReactConstants.TAG,
"Warning : attempted to resolve a non-existent react shadow node. reactTag=" + reactTag);
}
return rootTag;
}
/**
* Updates the root view size and re-render the RN surface.
*
* //TODO: change synchronization to integrate with new #render loop.
*/
private synchronized void updateRootSize(int rootTag, int newWidth, int newHeight) {
ReactShadowNode rootNode = getRootNode(rootTag);
if (rootNode == null) {
FLog.w(
ReactConstants.TAG,
"Tried to update size of non-existent tag: " + rootTag);
return;
}
ReactShadowNode newRootNode = rootNode.mutableCopy(rootNode.getInstanceHandle());
int newWidthSpec = View.MeasureSpec.makeMeasureSpec(newWidth, View.MeasureSpec.EXACTLY);
int newHeightSpec = View.MeasureSpec.makeMeasureSpec(newHeight, View.MeasureSpec.EXACTLY);
updateRootView(newRootNode, newWidthSpec, newHeightSpec);
completeRoot(rootTag, newRootNode.getChildrenList());
}
public void openInspectorConnection() {
if (mInspectorPackagerConnection != null) {
FLog.w(ReactConstants.TAG, "Inspector connection already open, nooping.");
return;
}
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
mInspectorPackagerConnection = new InspectorPackagerConnection(
getInspectorDeviceUrl(),
mPackageName,
mBundlerStatusProvider
);
mInspectorPackagerConnection.connect();
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
* This method will give JS the opportunity to receive intents via Linking.
*/
@ThreadConfined(UI)
public void onNewIntent(Intent intent) {
UiThreadUtil.assertOnUiThread();
ReactContext currentContext = getCurrentReactContext();
if (currentContext == null) {
FLog.w(ReactConstants.TAG, "Instance detached from instance manager");
} else {
String action = intent.getAction();
Uri uri = intent.getData();
if (Intent.ACTION_VIEW.equals(action) && uri != null) {
DeviceEventManagerModule deviceEventManagerModule =
currentContext.getNativeModule(DeviceEventManagerModule.class);
deviceEventManagerModule.emitNewIntentReceived(uri);
}
currentContext.onNewIntent(mCurrentActivity, intent);
}
}
@ThreadConfined(UI)
private void recreateReactContextInBackground(
JavaScriptExecutorFactory jsExecutorFactory,
JSBundleLoader jsBundleLoader) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.recreateReactContextInBackground()");
UiThreadUtil.assertOnUiThread();
final ReactContextInitParams initParams = new ReactContextInitParams(
jsExecutorFactory,
jsBundleLoader);
if (mCreateReactContextThread == null) {
runCreateReactContextOnNewThread(initParams);
} else {
mPendingReactContextInitParams = initParams;
}
}
private void attachRootViewToInstance(
final ReactRootView rootView) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
UIManager uiManagerModule = UIManagerHelper.getUIManager(mCurrentReactContext, rootView.getUIManagerType());
final int rootTag = uiManagerModule.addRootView(rootView);
rootView.setRootViewTag(rootTag);
rootView.runApplication();
Systrace.beginAsyncSection(
TRACE_TAG_REACT_JAVA_BRIDGE,
"pre_rootView.onAttachedToReactInstance",
rootTag);
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
Systrace.endAsyncSection(
TRACE_TAG_REACT_JAVA_BRIDGE,
"pre_rootView.onAttachedToReactInstance",
rootTag);
rootView.onAttachedToReactInstance();
}
});
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
private void tearDownReactContext(ReactContext reactContext) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.tearDownReactContext()");
UiThreadUtil.assertOnUiThread();
if (mLifecycleState == LifecycleState.RESUMED) {
reactContext.onHostPause();
}
synchronized (mAttachedRootViews) {
for (ReactRootView rootView : mAttachedRootViews) {
rootView.removeAllViews();
rootView.setId(View.NO_ID);
}
}
reactContext.destroy();
mDevSupportManager.onReactInstanceDestroyed(reactContext);
mMemoryPressureRouter.removeMemoryPressureListener(reactContext.getCatalystInstance());
}
@Override
public void onChildStartedNativeGesture(MotionEvent androidEvent) {
if (mReactInstanceManager == null || !mIsAttachedToInstance ||
mReactInstanceManager.getCurrentReactContext() == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS as the catalyst instance has not been attached");
return;
}
if (mJSTouchDispatcher == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS before the dispatcher is available");
return;
}
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, eventDispatcher);
}
@SuppressWarnings("unchecked")
static <T> T getFieldValue(Object target, String name, @Nullable Class type) {
type = type == null ? target.getClass() : type;
try {
Field field = type.getDeclaredField(name);
field.setAccessible(true);
return (T) field.get(target);
} catch (Exception e) {
FLog.w(ReactConstants.TAG, "Can't get " + type.getName() + " field " + name);
FLog.w(ReactConstants.TAG, e.getMessage());
}
return null;
}
private void dispatchJSTouchEvent(MotionEvent event) {
if (mReactInstanceManager == null || !mIsAttachedToInstance ||
mReactInstanceManager.getCurrentReactContext() == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS as the catalyst instance has not been attached");
return;
}
if (mJSTouchDispatcher == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS before the dispatcher is available");
return;
}
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher);
}
private void enableLayoutCalculation() {
if (mReactInstanceManager == null) {
FLog.w(
ReactConstants.TAG,
"Unable to enable layout calculation for uninitialized ReactInstanceManager");
return;
}
final ReactContext reactApplicationContext = mReactInstanceManager.getCurrentReactContext();
if (reactApplicationContext != null) {
reactApplicationContext
.getCatalystInstance()
.getNativeModule(UIManagerModule.class)
.getUIImplementation()
.enableLayoutCalculationForRootNode(getRootViewTag());
}
}