記錄自己分析RN的過程。
先看入口的MainActivity,它是繼承自ReactActivity 的刊头。
ReactActivity的內(nèi)容
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react;
import javax.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;
/**
* Base Activity for React Native applications.
*/
public abstract class ReactActivity extends Activity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
protected ReactActivity() {
mDelegate = createReactActivityDelegate();
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
* e.g. "MoviesApp"
*/
protected @Nullable String getMainComponentName() {
return null;
}
/**
* Called at construction time, override if you have a custom delegate implementation.
*/
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
@Override
protected void onPause() {
super.onPause();
mDelegate.onPause();
}
@Override
protected void onResume() {
super.onResume();
mDelegate.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mDelegate.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
mDelegate.onActivityResult(requestCode, resultCode, data);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mDelegate.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
}
@Override
public void onBackPressed() {
if (!mDelegate.onBackPressed()) {
super.onBackPressed();
}
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
public void onNewIntent(Intent intent) {
if (!mDelegate.onNewIntent(intent)) {
super.onNewIntent(intent);
}
}
@Override
public void requestPermissions(
String[] permissions,
int requestCode,
PermissionListener listener) {
mDelegate.requestPermissions(permissions, requestCode, listener);
}
@Override
public void onRequestPermissionsResult(
int requestCode,
String[] permissions,
int[] grantResults) {
mDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected final ReactNativeHost getReactNativeHost() {
return mDelegate.getReactNativeHost();
}
protected final ReactInstanceManager getReactInstanceManager() {
return mDelegate.getReactInstanceManager();
}
protected final void loadApp(String appKey) {
mDelegate.loadApp(appKey);
}
}
其中仗颈,這個類吧所有的操作都交給一個ReactActivityDelegate對象來執(zhí)行佛舱。
我想主要原因是,這個類需要經(jīng)常被繼承挨决,如果直接在這個類實現(xiàn)方法请祖,不免會讓其子類變得臃腫。使用代理的方法就避免了這個問題脖祈。
先看其最核心的入口肆捕,onCreate .這個類來創(chuàng)建視圖等。
我們在做安卓開發(fā)時一般在這類初始化視圖盖高。
使用setContentView傳入一個layout的id慎陵,或者一個view對象。
我們跟進Delegate中或舞,看到
protected void onCreate(Bundle savedInstanceState) {
boolean needsOverlayPermission = false;
if (getReactNativeHost().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Get permission to show redbox in dev builds.
if (!Settings.canDrawOverlays(getContext())) {
needsOverlayPermission = true;
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getContext().getPackageName()));
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
Toast.makeText(getContext(), REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
((Activity) getContext()).startActivityForResult(serviceIntent, REQUEST_OVERLAY_PERMISSION_CODE);
}
}
if (mMainComponentName != null && !needsOverlayPermission) {
loadApp(mMainComponentName);
}
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
}
對于androidM荆姆,請求了android.settings.action.MANAGE_OVERLAY_PERMISSION權(quán)限。
隨后判斷mMainComponentName 是否為空映凳。這個變量的初始化是在其構(gòu)造函數(shù)中
public ReactActivityDelegate(Activity activity, @Nullable String mainComponentName) {
mActivity = activity;
mMainComponentName = mainComponentName;
mFragmentActivity = null;
}
這個構(gòu)造函數(shù)的調(diào)用者是ReactActivity的create..方法
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName());
}
是通過getMainComponentName獲取的胆筒。而這個方法子類可以繼承和修改。
我們回到onCreate中诈豌。
調(diào)用 loadApp(mMainComponentName); 接著調(diào)用
DoubleTapReloadRecognizer (這個應該是雙擊R重新加載)
loadApp代碼
protected void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
getPlainActivity().setContentView(mReactRootView);
}
如果mReactRootView已經(jīng)有了仆救,就不需要load了。
調(diào)用createRootView創(chuàng)建矫渔。
protected ReactRootView createRootView() {
return new ReactRootView(getContext());
}
其實是調(diào)用了構(gòu)造函數(shù)彤蔽。轉(zhuǎn)到ReactRootView看一下。
public class ReactRootView extends SizeMonitoringFrameLayout implements RootView {
...
}
這是一個SizeMonitoringFrameLayout 庙洼,它又是一個FrameLayout顿痪。
好了∮凸唬總結(jié)來說蚁袭,在ReactActivity創(chuàng)建的時候使用了一個ReactRootView作為其跟視圖。
未完待續(xù)石咬。揩悄。。