react-native + as <react-native嵌入原生应用开发>

来源:互联网 发布:肺活量测量仪器软件 编辑:程序博客网 时间:2024/06/06 04:24

这几天开始根据react-native中文网进行react-native+android studio开发,但是在看了官网之后,你会发现项目并跑不起来,辗转几次,翻看别人博客,多是官网的照搬,在一个朋友的帮助下完成react-native的嵌入原生应用.
图一
MainActivity
图二
MyReactActivity

点击MainActivity<图一>中的start_react按钮 进入MyReactActivity<图二>
接着进入正题 react-native嵌入应用开发:

1.

在项目下创建package.json描述文件:

 npm init

这里写图片描述

图中红圈标注就是项目的描述信息:即包名,版本号,作者等等;接着看配置好的package.json

{  "name": "app",  "version": "1.0.0",  "description": "react demo",  "main": "index.js",  "scripts": {  },  "keywords": [    "react",    "test"  ],  "author": "houruixiang",  "license": "ISC",  "dependencies": {    "install": "^0.10.1",    "react": "^16.0.0-alpha.12",    "react-native": "^0.46.2"  }

然后在package.json中添加:

"start": "node node_modules/react-native/local-cli/cli.js start"
{  "name": "app",  "version": "1.0.0",  "description": "react demo",  "main": "index.js",  "scripts": {    "start": "node node_modules/react-native/local-cli/cli.js start",  },  "keywords": [    "react",    "test"  ],  "author": "houruixiang",  "license": "ISC",  "dependencies": {    "install": "^0.10.1",    "react": "^16.0.0-alpha.12",    "react-native": "^0.46.2"  }}

2.

配置资源文件assets

在package.jason,中加入:

"bundle-android": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --sourcemap-output app/src/main/assets/index.android.map --assets-dest android/app/src/main/res/"

3.

创建node_modules目录并把react和react-native下载到了其中

npm install --save react react-native

这样就创建了node_modules,里面是js的modules,最主要的就是react和react-native的代码;

4.

接下来在项目根目录中 手动 创建index.android.js文件,然后将下面的代码复制粘贴进来:

'use strict';import React, { Component } from 'react';import {  AppRegistry,  StyleSheet,  Text,  View,  ScrollView,  Image} from 'react-native';export default class ReactDemo extends Component {  render() {    let pic = {      uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'    };    return (        <ScrollView>          <Text style={{fontSize:20}}>Scroll me plz</Text>          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Text style={{fontSize:20}}>If you like</Text>          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Text style={{fontSize:20}}>Scrolling down</Text>          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Text style={{fontSize:20}}>What's the best</Text>          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Text style={{fontSize:20}}>Framework around?</Text>          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Image source={pic} style={{width: 193, height: 110}} />          <Text style={{fontSize:20}}>React Native</Text>        </ScrollView>    );  }}const styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: '#F5FCFF',  },  welcome: {    fontSize: 20,    textAlign: 'center',    margin: 10,  },  instructions: {    textAlign: 'center',    color: '#333333',    marginBottom: 5,  },});AppRegistry.registerComponent('ReactDemo', () => ReactDemo);

注意AppRegistry.registerComponent(‘项目名’, () => 项目名);项目名必须与自己工程一直,index.android.js的类名也必须与项目名一致

5.

android studio中相关包的依赖
4.1maven 和react-native依赖

在app->build.gradle中添加依赖:
android{    configurations.all {        resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'    }}dependencies {    ....    compile "com.facebook.react:react-native:+" // From node_modules.}

在项目<我的是reactDemo中添加>的build.gradle中添加依赖:

allprojects {    repositories {        ...        maven {            // All of React Native (JS, Android binaries) is installed from npm            url "$rootDir/node_modules/react-native/android"        }    }}

4.2.ndk的配置

在app->build.gradle中配置:

android {    compileSdkVersion 25    buildToolsVersion "25.0.2"    defaultConfig {    ...        ndk {            abiFilters "armeabi-v7a", "x86"        }    }     ...    }    packagingOptions {        exclude "lib/arm64-v8a"    }     ...}

6.

在清单文件AndroidManifest.xml中配置activity及权限

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.houruixiang.reactdemo">    <uses-permission android:name="android.permission.INTERNET" />    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity            android:name=".MyReactActivity"            android:label="@string/app_name"            android:theme="@style/Theme.AppCompat.Light.NoActionBar">        </activity>        <!--摇一摇-->        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />    </application></manifest>

7.

android下代码填写
MyReactActivity:

package com.example.houruixiang.reactdemo;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.provider.Settings;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;/** * Created by houruixiang on 2017/7/13. */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();        // 注意这里的HelloWorld必须对应“index.android.js”中的        // “AppRegistry.registerComponent()”的第一个参数        mReactRootView.startReactApplication(mReactInstanceManager, "ReactDemo", null);        setContentView(mReactRootView);    }    @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);    }}

MainActivity

package com.example.houruixiang.reactdemo;import android.content.Intent;import android.net.Uri;import android.os.Build;import android.provider.Settings;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final int OVERLAY_PERMISSION_REQ_CODE = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        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);            }        }        initEvent();    }    private void initEvent() {        Button btn = (Button) findViewById(R.id.start_react);        btn.setOnClickListener(this);    }    @Override    protected 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...                }            }        }    }    @Override    public void onClick(View v) {        startActivity(new Intent(this,MyReactActivity.class));    }}

8.

权限添加

在API 23之前配置运行react-native项目需要在手机设置–>应用管理–>项目<即本项目> 开启浮窗权限
在API 23之后,需要在代码中动态配置权限:

 @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        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);            }        }        initEvent();    }    .......    @Override    protected 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...                }            }        }    }

9.

第一次开启项目手动配置

在MyReactActivty界面 会红屏,需要摇晃手机进行设置:
图一
这里写图片描述

点击Dev Settings—>进入图二
图二
这里写图片描述

点击Animations FPS Summaries—>进入图三进行ip 配置

图三
这里写图片描述

这就是react-native嵌入原生app的步骤,欢迎完善,对于一些bug将会在后续博文中总结,欢迎提意见,关注;期待一起进步

原创粉丝点击