一、RN 呼叫安卓程式碼(簡單的實現方式)
RN
呼叫android
程式碼大致分為以下幾個步驟:
1、用android studio
開啟一個已經建立好的 RN
專案;
2、建立一個類 CommonModule
繼承自 ReactContextBaseJavaModule
,並重寫 getName()
方法,在該類中我們要暴露一些方法供 RN
呼叫;
class CommonModule(private val reactContext: ReactApplicationContext)
: ReactContextBaseJavaModule(reactContext) {
}
複製程式碼
- 實現
getName()
方法,改方法用來返回RN
程式碼需要尋找的類的名稱;
override fun getName(): String {
// 一定要有名字 RN程式碼要通過名字來呼叫該類的方法
return "CommonModule"
}
複製程式碼
- 建立暴露給
RN
呼叫的方法,並用@ReactMethod
註解修飾;
/**
* 加上 @ReactMethod 註解是為了暴露給RN呼叫的方法;
*
* 方法不能返回值,因為被呼叫的原生程式碼是非同步的,原生程式碼執行結束之後只能通過回撥函式或者傳送訊息給RN
*/
@ReactMethod
fun rnCallNative(msg: String) {
// 這個方法是說彈出一個彈窗到介面
Toast.makeText(reactContext, msg, Toast.LENGTH_LONG).show()
}
複製程式碼
3、建立類 CommonPackage
實現介面 ReactPackage
包管理器,並把第2步中建立好的 CommonModule
類新增進來;
class CommonPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
val list = ArrayList<NativeModule>()
list.add(CommonModule(reactContext))
return list
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
複製程式碼
4、將建立好的 CommonPackage
包管理器新增到 ReactPackage
列表中;也就是在 ReactNativeActivity
中的 onCreate
方法中新增:
class ReactNativeActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler {
private var mReactRootView: ReactRootView? = null
private var mReactInstanceManager: ReactInstanceManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val list = mutableListOf<ReactPackage>()
list.add(MainReactPackage()) // 預設
list.add(CommonPackage()) // 自定義Package
mReactRootView = ReactRootView(this)
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(application)
.setCurrentActivity(this)
//.setBundleAssetName("index.android.bundle")
.setJSBundleFile(CodePush.getJSBundleFile())// ! 此處為codePush載入JsBundle方式,預設為.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index") // ! 注意這裡的index指向入口的js檔案
//.addPackage(MainReactPackage())
.addPackages(list) // ! 此處為擴充套件Packages,預設為.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build()
// 注意這裡的 rn_sample 必須對應“index.js”中的 “AppRegistry.registerComponent()”的第一個引數
mReactRootView?.startReactApplication(mReactInstanceManager, "rn_sample", null)
setContentView(mReactRootView)
}
...
}
複製程式碼
5、在 RN
程式碼中用 NativeModules
元件去呼叫原生模組;
- 匯入元件,設定方法呼叫原生方法;
import {Alert, Button, NativeModules, StyleSheet, View} from 'react-native';
const commonModule = NativeModules.CommonModule;
function callAndroid() {
commonModule.rnCallNative('RN 呼叫 Android 原生~~');
}
複製程式碼
- 在
render
方法裡設定button
的點選事件直接呼叫自定義方法callAndroid
即可;
render() {
return (
<View style={styles.container}>
<Button title='call_android' onPress={callAndroid}/>
</View>
);
}
複製程式碼
到此,基本的 RN
呼叫安卓原生程式碼的方式就得以實現。
二、RN 用 Promise 機制與安卓原生程式碼通訊
在原生程式碼
CommonModule
類中建立橋接方法,當橋接的方法最後一個引數是Promise
物件,那麼該方法就會返回一個JS
的Promise
物件給對應的JS
方法。
1、首先需要在 CommonModule
中定義一個暴露給 RN
的方法,並且要用 @ReactMethod
標識;
@ReactMethod
fun rnCallNativePromise(msg: String, promise: Promise) {
Toast.makeText(reactContext, msg, Toast.LENGTH_LONG).show()
val componentName = name
promise.resolve(componentName)
}
複製程式碼
2、在 RN
程式碼中也是需要用 NativeModules
元件呼叫原生模組;
import {Alert, Button, NativeModules, StyleSheet, View} from 'react-native';
const commonModule = NativeModules.CommonModule;function callAndroidPromise() {
commonModule.rnCallNativePromise('RN Promise 呼叫 Android 原生~~')
.then((msg) => {
Alert.alert('promise 收到訊息', msg)
console.log("promise 收到訊息", msg)
})
.catch((error) => {
console.log(error)
})
}
複製程式碼
render() {
return (
<View style={styles.container}>
<Button title='call_android' onPress={callAndroid}/>
<Button title='call_android_promise' onPress={callAndroidPromise}/>
</View>
);
}
複製程式碼
三、RN 用 callback 回撥方式與安卓原生程式碼通訊
1、 同樣也是按照上面的方式,在原生模組中暴露一個橋接的方法給 RN
呼叫,引數傳入一個成功的回撥和一個失敗的回撥;
@ReactMethod
fun rnCallNativeCallback(success: Callback, error: Callback) {
try {
success.invoke(100, 200)
} catch (e: Exception) {
error.invoke(e.message)
}
}
複製程式碼
2、在 RN
程式碼中也是需要用 NativeModules
元件呼叫原生模組;
import {Alert, Button, NativeModules, StyleSheet, View} from 'react-native';
const commonModule = NativeModules.CommonModule;function callAndroidCallback() {
commonModule.rnCallNativeCallback((x, y) => {
Alert.alert('callback 收到訊息', x + ',' + y)
console.log('callback 收到訊息', x, y)
}, (error) => {
console.log(error)
})
}
複製程式碼
render() {
return (
<View style={styles.container}>
<Button title='call_android' onPress={callAndroid}/>
<Button title='call_android_promise' onPress={callAndroidPromise}/>
<Button title='call_android_callback' onPress={callAndroidCallback}/>
</View>
);
}
複製程式碼
最後,RN與安卓原生之間的通訊方式已經介紹完了,如有不對的地方,歡迎指正~~
完整的專案地址:github.com/iceCola7/rn…