React native 介面跳轉原生Android介面
阿新 • • 發佈:2019-02-07
最近在學習React native,正好看到RN介面跳轉原生的介面,但是根據網上的來 總是會報undefined is not an object (evaluating ‘NativeModules.IntentModule.startActivityFromJS’) 異常 仔細對照程式碼 都是一樣的 最後發現 你自定義的ReactPackage 需要再你的註冊Rn的Activity介面裡面新增下。
詳細程式碼如下(ps:我是用的Rn版本為 0.48.3):
1.定義跳轉的IntentModule;
import android.app.Activity;
import android.content.Intent;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
* Created by ly on 2017/9/27.
*/
public class IntentModule extends ReactContextBaseJavaModule {
public IntentModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "IntentModule";
}
//startActivityFromJS這個方法是我們自己寫的 然後需要新增@ReactMethod註解 才能讓RN呼叫
@ReactMethod
public void startActivityFromJS(String name, String params) {
try {
Activity currentActivity = getCurrentActivity();
if (null != currentActivity) {
Class toActivity = Class.forName(name);
Intent intent = new Intent(currentActivity, toActivity);
intent.putExtra("params", params);
currentActivity.startActivity(intent);
currentActivity.finish();
}
} catch (Exception e) {
throw new JSApplicationIllegalArgumentException(
"不能開啟Activity : " + e.getMessage());
}
}
}
2.定義ReactPackage註冊你的IntentModule:
import android.com.reactnativedemo.module.IntentModule;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Created by ly on 2017/9/27.
*/
public class MyReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new IntentModule(reactContext));
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
3.自定義Application:
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
/**
* Created by ly on 2017/9/27.
*/
public class App extends Application implements ReactApplication {
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
//新增你的ReactPackage
@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new MyReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
//=====>別忘記在清單檔案註冊
4.然後別忘記了 別忘記了 在你整合RN的activity介面裡面 要新增下你的ReactPackage
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
public class MainActivity extends AppCompatActivity 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())
//這邊要新增
.addPackage(new MyReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 注意這裡的MyReactNativeApp必須對應“index.android.js”中的
// “AppRegistry.registerComponent()”的第一個引數
mReactRootView.startReactApplication(mReactInstanceManager, "ReactNativeDemo", null);
setContentView(mReactRootView);
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, 1);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted...
}
}
}
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy();
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
5.然後是我的JS程式碼:
'use strict'
import React, {Component} from 'react';
import {View, Image} from 'react-native';
var Dimensions = require('Dimensions');
var width = Dimensions.get('window').width;
var height = Dimensions.get('window').height;
var {NativeModules} = require('react-native');
export default class SplashView extends Component {
componentDidMount() {
this.timer = setTimeout(() => {
//這邊就是跳轉的地方 NativeModules.IntentModule.startActivityFromJS("android.com.reactnativedemo.TestActivity", "跳轉傳參")
}, 3000);
}
render() {
let picUrl = {uri: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1506482681622&di=409d9146bcf7fc741787753c8d06a118&imgtype=0&src=http%3A%2F%2Fimg.juweixin.com%2Farticle%2F2016%2F1104%2Ft_986c087f4b8a27e4831bc216412fda0b.jpg'};
return (
<View style={{flex: 1}}>
<Image source={picUrl} style={{width: width, height: height}} resizeMode={Image.resizeMode.cover}/>
</View>
);
}
componentUnmount(){
this.timer && clearTimeout(this.timer);
}
}