首先说说情况吧,公司需要原生嵌入ReactNative,迫于需要,要搞起来。看着iOS就搞了20分钟,感觉Android就算麻烦也不能太麻烦的,结果还是自己太年轻了。下面就是我遇到的各种问题,希望对看到的朋友能有帮助

(我用的是ReactNative版本为0.32.0)


1.首先集成的项目目录

我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的

Android项目目录是跟node_modules是在一个目录下的。

我试过把node_modules集成在Android项目下面的情况,不过没有弄成,所以我换乘来

这种了(有时间可以再试试)



2.第二步就是跟官网和很多教程一样的配置环境了

2.1 在我们Android项目的build.gradle中添加React Native依赖,然后同步,具体代码如下:

compile 'com.facebook.react:react-native:0.32.0'

在此说一下,我也是忘记在哪个大神博客下看的了,如果版本写的是“+”的话,下载的react native版本就是0.20.0的版本,会报一个错,就是版本不符合的错误,“Module 0 is not a registered callable moudle”,这个Google了一下,说是reactnative版本跟服务器的版本不符合,改正了就按着我的步骤三的第一种方法做就可以了,注释掉第三个重写的方法。

2.2紧接着我们需要在项目AndroidManifest.xml中加入网络访问权限

android:name="android.permission.INTERNET" />
还有一个activity就是设置菜单,发现好多里面都没有,我就先放在这里了

android:name="com.facebook.react.devsupport.DevSettingsActivity" />


2.3 android/build.gradle文件中(注意跟上面的路径不同)加入本地React Native的maven目录(现在React Native的所有组件,无论JS还是Android的预编译包,都是通过npm分发的了):

我是在两个           jcenter()    后面都添加了这个方法

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


3.在Activity中添加代码

这里有两种方法都是可以加载的。

第一种:

public class MainActivity extends ReactActivity {     @Override    protected String getMainComponentName() {        return "MyAwesomeApp";    }     @Override    protected boolean getUseDeveloperSupport() {        return BuildConfig.DEBUG;    }  //   @Override //   protected List getPackages() { //      return Arrays.asList( //               new MainReactPackage() //       );    }}

? 由于我使用的是第0.32.0版本的react native,所以运行的时候,最后一个重写的方法会报错的,于是就注释掉了,但是不要担心,getPackages方法写到MainApplication里就可以了
public class MainApplication extends  Application implements ReactApplication {    private Application context;    @Override    public ReactNativeHost getReactNativeHost() {        context = this;        ReactNativeHost host = null;        if (host==null){            host = new ReactNativeHost(context) {                @Override                protected boolean getUseDeveloperSupport() {                    return false;                }                @Override                protected List getPackages() {                    return Arrays.asList(                            new MainReactPackage(),                            new IntentReactPackage()                    );                }            };        }        return host;    }}

如果不写的话,会有一个Application强转错误的
第二种,
public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {    private ReactRootView mReactRootView;    private ReactInstanceManager mReactInstanceManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //创建一个ReactRootView,把它设置成Activity的主视图        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();        mReactRootView.startReactApplication(mReactInstanceManager, "MyAwesomeApp", null);        setContentView(mReactRootView);    }    @Override    public void invokeDefaultOnBackPressed() {        super.onBackPressed();    }    //传递一些Activity的生命周期事件到ReactInstanceManager,这是的JavaScript代码可以控制当前用户按下返回按钮的时候作何处理(譬如控制导航切换等等)。如果JavaScript端不处理相应的事件,你的invokeDefaultOnBackPressed方法会被调用。默认情况,这会直接结束你的Activity。    @Override    protected void onPause() {        super.onPause();        if (mReactInstanceManager != null) {            mReactInstanceManager.onHostPause();        }    }    @Override    protected void onResume() {        super.onResume();        if (mReactInstanceManager != null) {            mReactInstanceManager.onHostResume(this,this);        }    }    @Override    public void onBackPressed() {//        mReactInstanceManager.showDevOptionsDialog();        Toast.makeText(this, "dianjialefanhuijian", Toast.LENGTH_SHORT).show();        if (mReactInstanceManager != null) {            mReactInstanceManager.onBackPressed();        } else {            super.onBackPressed();        }    }    //我们需要改动一下开发者菜单。默认情况下,任何开发者菜单都可以通过摇晃或者设备类触发,不过这对模拟器不是很有用。所以我们让它在按下Menu键的时候可以显示    @Override    public boolean onKeyUp(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {            mReactInstanceManager.showDevOptionsDialog();            return true;        }        return super.onKeyUp(keyCode, event);    }}

我开始使用的是第一种,但是后来发现使用第一种的话,最后运行的话只能打包固定的代码,并不能实现热更新(毕竟新手,没有发现这么搞),所以果断改第二种了,修改js文件直接就能reload实现了,非常的嗨

4.添加react native包
这就比较简单了,看了好多的文档都是这么写的,也可以直接从init 的项目里拷过来就好,或者按着官方的来就好

$ npm init

跟着步骤回车就好了,然后好像输入个yes

然后就发现有了一个package.json文件

{  "name": "testRN",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "start": "node node_modules/react-native/local-cli/cli.js start"  },  "author": "",  "license": "ISC",  "dependencies": {    "react": "15.3.1",    "react-native": "^0.32.0"  }}
千万要记住,这个里面的react-native版本一定要和前面gradle的版本一样,不然就出现了那个“Module  0”的版本不一致的错误了,这个错误就看第三步的方法一就好了


然后就是 npm install ,导入react包了


然后就是   

curl -o .flowconfig  https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

做一下flow配置    虽然现在不知道是为了什么,但是每个人都这么做

5.添加Js代码

import React, { Component } from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    ToastAndroid} from 'react-native';var { NativeModules } = require('react-native'); class MyAwesomeApp extends Component {    constructor(props) {        super(props);    }    render() {        return(                           哈哈哈哈哈哈哈哈                    )    }}AppRegistry.registerComponent('MyAwesomeApp', () => MyAwesomeApp);  

6.运行Demo

开开reactnative的服务器,npm start

在studio中运行demo,会发现,出现一行“哈哈哈哈”



注:可能会出现java.lang.RuntimeException: Could not get BatchedBridge, make sure your bundle is packaged correctly这个错误,Google就有解决方法,就是在命令行里运行

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

注意assets的目录,我是在里面直接新建了index.android.bundle和index.android.map两个空文件,然后运行的,会自动往里面写入代码,然后运行就可以了



本人第一次写这些自己的经验,有不足之处,希望大家海涵,因为是后来写的,有些东西可能还是忘记了,如果有碰到什么问题的话,可以直接回复,谢谢


我在自己做的时候,也参考了好多大神的文章,都有很大帮助,他们的文章都在百度的前几个,所以也好找,

谢谢观看

更多相关文章

  1. 【攻克Android (2)】Android各版本、app开发流程、apk构建过程
  2. 我的Android NDK之旅(五),在Mac上用eclipse手动编写代码向android开
  3. android开源代码
  4. 简单的 Android 系统主要版本对比图表
  5. Android 混淆代码学习以及Android加密工具--APKProtect的使用
  6. Android获取App版本号和版本名
  7. android代码实现免提功能

随机推荐

  1. 在php中获取引荐来源网址(包括参数)
  2. php隔两行换色
  3. ThinkPHP3.2.3框架下where的组合查询and
  4. 关于uoloadify不能显示效果原因(thinkphp
  5. PHP 常见的数据加密技术
  6. 如何从0-X的PHP中获得一个加密的强整数?
  7. PHP 使用 OSS 批量上传图片
  8. PHP 5.0 到 7.1 常用语法糖(个人整理)
  9. PHP基础 文件流
  10. 使用wamp扩展php时出现服务未启动的解决