React Native在Android當中實踐(四)——程式碼整合

yang0range發表於2018-10-10

React Native在Android當中實踐(一)——背景介紹

React Native在Android當中實踐(二)——搭建開發環境

React Native在Android當中實踐(三)——整合到Android專案當中

React Native在Android當中實踐(四)——程式碼整合

React Native在Android當中實踐(五)——常見問題

程式碼整合

Android Studio的環境配置完成之後 接下來我們開始對程式碼進行整合

index.js檔案

首先在專案根目錄中建立一個空的index.js檔案。(注意在0.49版本之前是index.android.js檔案) index.js是React Native應用在Android上的入口檔案。而且它是不可或缺的!

新增你自己的React Native程式碼

在這裡方便測試 我們只是簡簡單單寫一個js檔案進行測試

import React from 'react';import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';
class HelloWorld extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.hello}>Hello, World</Text>
      </View>
    )
  }
}var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});
 
AppRegistry.registerComponent('MyReactNativeApp', () => HelloWorld);
複製程式碼

在這裡特別要注意的是:

React Native在Android當中實踐(四)——程式碼整合
這個名稱要和package.json當中的
React Native在Android當中實踐(四)——程式碼整合
保持一致,否則會出現異常。

配置許可權以便開發當中的紅屏錯誤能夠正確的顯示。

如果你的應用會執行在Android 6.0(API level 23)或更高版本,請確保你在開發版本中有開啟懸浮窗(overlay)許可權。你可以在程式碼中使用Settings.canDrawOverlays(this);來檢查。之所以需要這一許可權,是因為我們會把開發中的報錯顯示在懸浮窗中(僅在開發階段需要)。在Android 6.0(API level 23)中使用者需要手動同意授權。具體請求授權的做法是在onCreate()中新增如下程式碼。其中OVERLAY_PERMISSION_REQ_CODE是用於回傳授權結果的欄位。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.canDrawOverlays(this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                   Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
    }
}
Finally, the onActivityResult() method (as shown in the code below) has to be overridden to handle the permission Accepted or Denied cases for consistent UX.
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                // SYSTEM_ALERT_WINDOW permission not granted...
            }
        }
    }
}
複製程式碼

如果不需要開發者,則不需要以上相關配置。

執行React Native

首先需要在一個Activity中建立一個ReactRootView物件,然後在這個物件之中啟動React Native應用,並將它設為介面的主檢視。 如果你想在安卓5.0以下的系統上執行,請用 com.android.support:appcompat 包中的 AppCompatActivity 代替 Activity 。

public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意這裡的MyReactNativeApp必須對應“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一個引數
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);  

        setContentView(mReactRootView);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
}
複製程式碼

如果你使用的是 Android Studio , 可以使用Alt + Enter快捷鍵來自動為MyReactActivity類補上缺失的import語句。注意BuildConfig應該是在你自己的包中自動生成,無需額外引入。千萬不要從com.facebook...的包中引入! 我們需要把 MyReactActivity 的主題設定為 Theme.AppCompat.Light.NoActionBar ,因為裡面有許多元件都使用了這一主題。

 <activity
   android:name=".MyReactActivity"
   android:label="@string/app_name"
   android:theme="@style/Theme.AppCompat.Light.NoActionBar">
 </activity>
複製程式碼

一個ReactInstanceManager可以在多個activities或fragments間共享。 You will want to make your own ReactFragment or ReactActivity and have a singleton holder that holds a ReactInstanceManager. When you need the ReactInstanceManager (e.g., to hook up the ReactInstanceManager to the lifecycle of those Activities or Fragments) use the one provided by the singleton. 下一步我們需要把一些activity的生命週期回撥傳遞給ReactInstanceManager:

@Overrideprotected void onPause() {
    super.onPause();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onHostPause(this);
    }
}
@Overrideprotected void onResume() {
    super.onResume();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onHostResume(this, this);
    }
}
@Overrideprotected void onDestroy() {
    super.onDestroy();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onHostDestroy();
    }
}
複製程式碼

我們還需要把後退按鈕事件傳遞給React Native:

@Override
 public void onBackPressed() {
    if (mReactInstanceManager != null) {
        mReactInstanceManager.onBackPressed();
    } else {
        super.onBackPressed();
    }
}
@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
        mReactInstanceManager.showDevOptionsDialog();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}
複製程式碼

現在activity已就緒,可以執行一些JavaScript程式碼了。 在新版本的React Native的整合不必這麼麻煩 只需要簡單的繼承 ReactActivity 然後實現以下幾個方法

@Override
protected String getMainComponentName() {
    return null;
}

@Override
protected boolean getUseDeveloperSupport() {
    return false;
}

@Override
protected List<ReactPackage> getPackages() {
    return null;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}
複製程式碼

其中

protected String getMainComponentName() {
    return null;
}
複製程式碼

方法需要返回的名稱即為 注意這裡的MyReactNativeApp必須對應“index.android.js”中的 “AppRegistry.registerComponent()”的第一個引數 名稱。 如圖:

React Native在Android當中實踐(四)——程式碼整合
React Native在Android當中實踐(四)——程式碼整合
React Native在Android當中實踐(四)——程式碼整合
最後我們也需要自定義一個Application 否則執行時會報錯
React Native在Android當中實踐(四)——程式碼整合

public class MyApplication extends Application implements ReactApplication {
    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage()
            );
        }


    };
}
複製程式碼

在AndroidManifest.xml當中增加

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
複製程式碼

這個是除錯的Activity,若需要我們要整合到我們專案中的。 到此為止,ReactNative 整合到已有專案中完成!!!迫不及待的執行試試吧!! 執行ReactNative 首先,在Terminal當中執行 npm start命令(若整合了yarn 則直接執行yarn start即可) 若出現

React Native在Android當中實踐(四)——程式碼整合
則表示成功。為了確認 我們可以在瀏覽器當中輸入如下地址 http://localhost:8081/index.android.js 瀏覽器顯示我們的js檔案,則表示我們已經整合成功,如下圖。
React Native在Android當中實踐(四)——程式碼整合
然後執行專案
React Native在Android當中實踐(四)——程式碼整合
之所以有這個許可權,是因為在React Native測試環境下會如果有異常會有彈層所以我們允許許可即可。然後React Native正式的情況則不會有這個許可權。設定地方在Application當中的
React Native在Android當中實踐(四)——程式碼整合
這個地方進行配置

相關文章