RN
調用android
代碼大體分爲如下幾個步驟:react
一、用android studio
打開一個已經建立好的 RN
項目;android
二、建立一個類 CommonModule
繼承自 ReactContextBaseJavaModule
,並重寫 getName()
方法,在該類中咱們要暴露一些方法供 RN
調用;git
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()
}
複製代碼
三、建立類 CommonPackage
實現接口 ReactPackage
包管理器,並把第2步中建立好的 CommonModule
類添加進來;github
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()
}
}
複製代碼
四、將建立好的 CommonPackage
包管理器添加到 ReactPackage
列表中;也就是在 ReactNativeActivity
中的 onCreate
方法中添加:react-native
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)
}
...
}
複製代碼
五、在 RN
代碼中用 NativeModules
組件去調用原生模塊;promise
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
調用安卓原生代碼的方式就得以實現。bash
在原生代碼
CommonModule
類中建立橋接方法,當橋接的方法最後一個參數是Promise
對象,那麼該方法就會返回一個JS
的Promise
對象給對應的JS
方法。app
一、首先須要在 CommonModule
中定義一個暴露給 RN
的方法,而且要用 @ReactMethod
標識;異步
@ReactMethod
fun rnCallNativePromise(msg: String, promise: Promise) {
Toast.makeText(reactContext, msg, Toast.LENGTH_LONG).show()
val componentName = name
promise.resolve(componentName)
}
複製代碼
二、在 RN
代碼中也是須要用 NativeModules
組件調用原生模塊;ide
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
調用,參數傳入一個成功的回調和一個失敗的回調;
@ReactMethod
fun rnCallNativeCallback(success: Callback, error: Callback) {
try {
success.invoke(100, 200)
} catch (e: Exception) {
error.invoke(e.message)
}
}
複製代碼
二、在 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…