Android 混合开发
来源:互联网 发布:mac在ps没有足够ram 编辑:程序博客网 时间:2024/06/06 20:35
最近自己也是刚在学习React Native的知识,在学习到React Native 嵌入到原生应用的时候,感觉遇到了各种坑,这里做一下记录。若有说得不对的地方,谢谢大家纠正。
React Native嵌入到原生应用的教程在其官方指导文档里也有,但是感觉很多注意点没讲到,现在,我们就一步步来,我们这里的前提是开发环境已经搭配好。
第一步,在 Android Studio 上新建一个工程,这一步没什么好说的,然后在main目录下面创建一个assets 的文件夹。
第二步,打开下面的终端 Terminal,分别执行以下三条语句:
npm initnpm install --save react react-nativecurl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
先输入 npm init ,然后会出现下面的情况,划红线的都是需要自己输入的,看着我的随便写点就行
执行第二条命令
npm install --save react react-native,执行完之后你会发觉多了一个叫node_modules的文件夹,接着执行第三条命令
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig执行完,第三条命令之后又会生成一个.flowconfig的文件
第三步,将
"start": "node node_modules/react-native/local-cli/cli.js start"
这条语句copy到 data.json中的scripts中,如下图第四步,项目根目录中创建index.android.js
文件,然后将下面的代码复制粘贴进来:
'use strict';import React from 'react';import { AppRegistry, StyleSheet, Text, View} from 'react-native';class HelloWorld extends React.Component { render() { return ( <View style={styles.container}> <Text style={styles.hello}>Hello, World</Text> </View> ) }}var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', }, hello: { fontSize: 20, textAlign: 'center', margin: 10, },});AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
第五步,给工程添加React Native依赖包,如果你想下载一个随意版本的依赖包【建议下载最新版本的React Native依赖包】,就在你APP module下面的build.gradile文件中 的 dependencies中添加 compile "com.facebook.react:react-native:+" // From node_modules.
dependencies { ... compile "com.facebook.react:react-native:+" // From node_modules. }如果你不想下载一个随意的版本的React Native依赖包,你可以指定下你要下载的React Native依赖包的版本,首先查询下当前最新的React Native依赖包版本,执行下面这段话,(reactnative的npm包的地址为:https://www.npmjs.com/package/react-native),或者采用命令npm info react-native进行查看:
发觉当前最新的版本是0.39.2,那你就将 compile "com.facebook.react:react-native:+"改成 compile "com.facebook.react:react-native:0.39.2"即可
若发觉报错,说找不到当前的依赖包,如下面的错误:
说明你下载的依赖包版本 与当前APP 的build.gradile中dependiences 中过的依赖包的版本不一致,这时你可以执行如下的如句,下载特定的依赖包,
npm install --save react-native@版本号 //我这里就输入:npm install --save react-native@0.39.2
第六步,向你的工程随对应的build.gradile文件中添加如下这段
allprojects { repositories { ... maven { // All of React Native (JS, Android binaries) is installed from npm // url "$rootDir/../node_modules/react-///native/android" 官方给的是这一句,但是用这一句有时有问题 url "$rootDir/node_modules/react-native/android" } } ...}然后, 因为修改了build.guild文件,所以要async 一下工程,
不出意外,可能就会报下面的错误:
不要慌,在你的应用程序build.gradle添加内的下列Android { }:
configurations.all { resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'}
添加完成之后,再重新Async Now 一下,就行了
第七步,添加
<uses-permission android:name="android.permission.INTERNET" /><activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />到AndroidManifest.xml中
检查下刚才下载的React native依赖包版本是否正确,展开 External Libraries,发觉当前React native依赖包版本是0.39.2【也可以输入命令:react-native --version 查看当前react native的版本号,若不一致,则可执行
npm install --save react-native@版本号下载特定的版本】,正确,执行下一步,添加原生代码
第八步,添加原生代码
创建一个类,继承ReactActivity,然后必须要重写 getMainComponentName方法,将你index.android.js中注册的组件的名字作为返回值,即默认为HelloWorld
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
以下是我创建的ReactActivity子类:
package com.example.administrator.reactejp;import android.os.Bundle;import android.view.KeyEvent;import com.facebook.react.ReactActivity;import com.facebook.react.ReactInstanceManager;import com.facebook.react.ReactRootView;import com.facebook.react.common.LifecycleState;import com.facebook.react.shell.MainReactPackage;/** * Created by Administrator on 2017/1/8. */public class MyReactActivity extends ReactActivity { 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(); mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null); setContentView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @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 protected void onDestroy() { super.onDestroy(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostDestroy(); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } //该方法与弹出Reload的dialog相关,不重写,可能不能弹出dialog @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); }}
除此之外,我们还需要定义一个ReactApplication的子类,不然运行时时会报错的,以下是我的重写的
package com.example.administrator.reactnativedemo;import android.app.Application;import android.support.v4.*;import com.facebook.react.ReactApplication;import com.facebook.react.ReactNativeHost;import com.facebook.react.ReactPackage;import com.facebook.react.shell.MainReactPackage;import java.util.Arrays;import java.util.List;/** * Created by Administrator on 2016/12/23. */public class MyReactApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost=new ReactNativeHost(this) { @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage() ); } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; }}
这里有一点需要注意:
这两个类中的BuildConfig并没有导包,而是用了自动生成的一个BuildConfig.java的文件,如下
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.administrator.reactnativedemo/com.example.administrator.reactnativedemo.MyReactActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.facebook.react.ReactApplication
我一直不知道为什么会报类型转换异常的错误,找了好久才知道,已经要在AndroidMainfaist.xml清单文件中指明当前Application的name属性值为你定义的那个ReactApplication子类的名字,这里即为MyReactApplication
检查一下刚才执行的npm start 命令是否异常,若异常了重写执行一下该命令即可,然后再重新运行一下程序,发觉还是报错了,但错误发生了变化,如下所示:
以下方法来自百度。
方法一:【推荐使用方法】
进入项目,在android/app/src/main下新建assets目录,关闭掉原来的npm,分别执行以下命令:
react-native startreact-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/在assets文件夹下会生成index.android.bundle文件
方法二:
进入项目,在android/app/src/main下新建assets目录
在package.json中配置下面代码
"scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "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/" },
再重新运行下程序,若还是有错,再重新运行试两次,一般都可以,到此为止,你就会看到下面的画面:【注:要确定模拟器连接网络了】
在确保npm没挂的情况下,运行结果如下:
到这里为止,终于成功了!
补充:若出现Could not connect to development server,一般是npm报异常了,如果是的话,就执行 npm start 命令即可,如果不是,很有可能就是网络问题,这里提供种方法解决网络问题:
第一种:最常见的方式,点击上图红框区域,弹出一个dialog,选择Dev Setting,以下几张图片来自:http://www.jianshu.com/users/e630681e7001/latest_articles
将localHost换成,你的电脑的IP地址
最后,感谢http://www.jianshu.com/users/e630681e7001/latest_articles
- Android 混合开发 相关
- Android 混合开发
- Android+H5混合开发
- Android App混合开发
- Android混合开发
- Android混合开发JSBridge
- android混合开发前奏
- 混合开发-cordova打包Android
- 谈谈Android App混合开发
- 谈谈Android App混合开发
- Android和HTML5混合开发
- Android混合开发全解析
- 谈谈Android App混合开发
- android混合开发之unity
- 谈谈Android App混合开发
- 浅谈android、web混合开发
- Android App混合开发----Hybrid开发
- android之Java+html+javascript混合开发
- 《python 入门经典》读书笔记
- Codeforces 545D Queue【贪心+模拟】
- bindService启动的Service的生命周期
- Maya配置
- 区分int *p,int *p[],int(*p)[]及其初始化
- Android 混合开发
- LFS学习心得
- TensorFlow之MNIST机器学习入门
- 微信小程序学习 -- 项目开发目录结构简析
- Linux脚本
- MFC使用EasySize类自动调整对话框上控件的布局
- 一个面试题引发的蝴蝶效应
- 相机标定之一:相机模型(读multiple view geometry in computer vision)
- I 帧和 IDR 帧的区别