1. 程式人生 > >React native 介面跳轉原生Android介面

React native 介面跳轉原生Android介面

最近在學習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);
    }
}