React Native 안드로이드 첫 화면 화이트 화면 최적화
android에서 어떤 rn 모듈의 입구 단추를 누르면 rn의activity가 rn의 페이지에 나타나는 과정에서 뚜렷한 백색 화면 현상이 나타난다. 서로 다른 기종이 다르고 (cpu가 좋은 백색 화면 시간이 짧음) 약 1s에서 2s의 시간이 걸린다.
이 현상은 실제 기기에서만 발생할 수 있으며, 시뮬레이터에서는 전혀 초로 켜지지 않습니다.
최적화 분석
도구 분석을 통해 문제는 다음과 같은 코드에 있다.
ReactRootView mReactRootView = createRootView();
mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
ReactActivity의 onCreate()에 대한 전체 코드는 다음과 같습니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
// Get permission to show redbox in dev builds.
if (!Settings.canDrawOverlays(this)) {
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(serviceIntent);
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
}
}
mReactInstanceManager = createReactInstanceManager();
ReactRootView mReactRootView = createRootView();
mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
setContentView(mReactRootView);
}
문제가 발생한 원인을 알게 되면 우리는 어떻게 최적화에 착수하는지 알게 된다.우리가 먼저 생각한 건: - 메모리 교환 시간.
1단계:
캐시 루트 view 관리자는 주로 캐시 루트 view 대상을 초기화하고 캐시하는 데 사용됩니다.
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewParent;
import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactRootView;
import java.lang.reflect.Field;
/**
* view
*/
public class RNCacheViewManager {
private static ReactRootView mRootView = null;
private static ReactInstanceManager mManager = null;
private static AbsRnInfo mRnInfo = null;
//
public static void init(Activity act, AbsRnInfo rnInfo) {
init(act, rnInfo, null);
}
public static void init(Activity act, AbsRnInfo rnInfo, Bundle launchOptions) {
if (mManager == null) {
updateCache(act, rnInfo, launchOptions);
}
}
public static void updateCache(Activity act, AbsRnInfo rnInfo) {
updateCache(act, rnInfo, null);
}
// cache, cache
public static void updateCache(Activity act, AbsRnInfo rnInfo, Bundle launchOptions) {
mRnInfo = rnInfo;
mManager = createReactInstanceManager(act);
mRootView = new ReactRootView(act);
mRootView.startReactApplication(mManager, rnInfo.getMainComponentName(), launchOptions);
}
// , private,
public static void setModuleName(String moduleName) {
try {
Field field = ReactRootView.class.getDeclaredField("mJSModuleName");
field.setAccessible(true);
field.set(getReactRootView(), moduleName);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
// , private,
public static void setLaunchOptions(Bundle launchOptions) {
try {
Field field = ReactRootView.class.getDeclaredField("mLaunchOptions");
field.setAccessible(true);
field.set(getReactRootView(), launchOptions);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static ReactRootView getReactRootView() {
if(mRootView==null){
throw new RuntimeException(" view !");
}
return mRootView;
}
public static ReactInstanceManager getReactInstanceManager() {
if(mManager==null){
throw new RuntimeException(" view !");
}
return mManager;
}
public static AbsRnInfo getRnInfo() {
if(mRnInfo==null){
throw new RuntimeException(" view !");
}
return mRnInfo;
}
public static void onDestroy() {
try {
ViewParent parent = getReactRootView().getParent();
if (parent != null)
((android.view.ViewGroup) parent).removeView(getReactRootView());
} catch (Throwable e) {
e.printStackTrace();
}
}
public static void clear() {
try {
if (mManager != null) {
mManager.onDestroy();
mManager = null;
}
if (mRootView != null) {
onDestroy();
mRootView = null;
}
mRnInfo = null;
} catch (Throwable e) {
e.printStackTrace();
}
}
private static ReactInstanceManager createReactInstanceManager(Activity act) {
ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
.setApplication(act.getApplication())
.setJSMainModuleName(getRnInfo().getJSMainModuleName())
.setUseDeveloperSupport(getRnInfo().getUseDeveloperSupport())
.setInitialLifecycleState(LifecycleState.BEFORE_RESUME);
for (ReactPackage reactPackage : getRnInfo().getPackages()) {
builder.addPackage(reactPackage);
}
String jsBundleFile = getRnInfo().getJSBundleFile();
if (jsBundleFile != null) {
builder.setJSBundleFile(jsBundleFile);
} else {
builder.setBundleAssetName(getRnInfo().getBundleAssetName());
}
return builder.build();
}
}
단계 2
ReactActivity를 다시 쓰면 복사해서 고칠 수도 있고 계승해서 쓸 수도 있습니다. 주로 onCreate와 onDestroy를 다시 쓰면 나머지 코드가 움직이지 않습니다.onCreate 방법에서 캐시 루트 view 관리자를 사용하여 루트 view 대상을 다시 만들지 않고 가져옵니다.
onCreate() 코드
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (RNCacheViewManager.getRnInfo().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
// Get permission to show redbox in dev builds.
if (!Settings.canDrawOverlays(this)) {
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(serviceIntent);
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
}
}
mReactInstanceManager = RNCacheViewManager.getReactInstanceManager();
ReactRootView mReactRootView = RNCacheViewManager.getReactRootView();
setContentView(mReactRootView);
}
onDestroy 방법에서 원래의 mReactInstanceManager를 다시 호출할 수 없습니다.Destroy () 방법입니다. 그렇지 않으면 rn이 초기화한 대상은 소각되고 다음에는 사용할 수 없습니다.루트 뷰의parent 대상을 마운트 해제해야 합니다. 그렇지 않으면 다음에 set Content View에서 오류가 발생합니다.protected void onDestroy() {
RNCacheViewManager.onDestroy();
super.onDestroy();
}
RNCacheViewManager의 onDeatory 코드
public static void onDestroy() {
try {
ViewParent parent = getReactRootView().getParent();
if (parent != null)
((android.view.ViewGroup) parent).removeView(getReactRootView());
} catch (Throwable e) {
e.printStackTrace();
}
}
단계 3
앱이 시작될 때 캐시 루트 뷰 관리자를 초기화합니다.
RNCacheViewManager.init((Activity) context, new RnInfo(moduleName, launchOptions));
RnInfo 솔리드 클래스 코드:public class RnInfo extends AbsRnInfo {
private String mModuleName;
private Bundle mLaunchOptions;
public RnInfo(String moduleName) {
this.mModuleName = moduleName;
}
public RnInfo(String moduleName, Bundle launchOptions) {
this.mModuleName = moduleName;
this.mLaunchOptions = launchOptions;
}
@Nullable
@Override
public Bundle getLaunchOptions() {
return mLaunchOptions;
}
@Override
public String getMainComponentName() {
return mModuleName;
}
@Override
public String getJSMainModuleName() {
return RNKeys.Default.DEf_JS_MAIN_MODULE_NAME;
}
@Nullable
@Override
public String getJSBundleFile() {
return RNManager.getJsBundlePath();
}
@Override
public boolean getUseDeveloperSupport() {
return true;
}
@Override
public List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new BBReactPackage()
);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.