首页 > 代码库 > lz的第一个RN项目

lz的第一个RN项目

这是lz 成功在原有项目上集成的第一个ReactNative 项目.
参考官方网址: http://reactnative.cn/docs/0.43/integration-with-existing-apps.html#content

Lz 寄语: 写在前面的:
1)APP 的build.gradle 最小sdk>=16

技术分享

2)关于乱码问题, index.andorid.js文件应该F12另存为UTF-8 无 BOM 格式

技术分享 

3)每次修改JS文件后, 第一次运行之前, 可能需要删除build 文件

技术分享

4)第一次可能无法运行, 无法连接到服务器, 这是因为需要npm start , 然后reload 即可,

技术分享

5)在Genymation中, RR可能失效, 无法重载


把React Native组件植入到Android应用中有如下几个主要步骤:
1.首先当然要了解你要植入的React Native组件。
2.在Android项目根目录中使用npm来安装react-native ,这样同时会创建一个node_modules/的目录。
3.创建js文件,编写React Native组件的js代码。
4.在build.gradle文件中添加com.facebook.react:react-native:+,以及一个指向node_nodules/目录中的react-native预编译库的maven路径。
5.创建一个React Native专属的Activity,在其中再创建ReactRootView。
6.启动React Native的Packager服务,运行应用。
7.根据需要添加更多React Native的组件。
8.在真机上运行、调试。
9.打包。
10.发布应用,升职加薪,走向人生巅峰!

(一)开发环境准备, 详细参照<关于ReactNativieAndroid配置>
(二)在项目中添加JS代码
a)打开doc 命令行
b)Cd / 回退到根目录;
c)E: 目标盘符, 这里举例用E盘;
d)Cd E:\lzAndroidWorkSpace\ReactNativeWorkSpace\Test 目标项目的根目录
i.PS@lz寄语: 此处建议最好修改项目的文件名为android
ii.技术分享

e)Npm init npm init创建了一个空的node模块(其实就是创建了一个package.json描述文件)
i.PS@lz寄语: 需要配置的参数如下

技术分享

f)Npm install --save react react-native npm install则创建了node_modules目录并把react和react-native下载到了其中
i.PS@lz寄语: 建议下载完之后, 直接去官方例子拷贝node_modules文件
g)curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
第三步curl命令,其实质是下载.flowconfig配置文件,这个文件用于约束js代码的写法。这一步非必需,可跳过。
h)在升生成的package.json中scripts字段添加
"start": "node node_modules/react-native/local-cli/cli.js start"
i.PS@lz寄语: 注意, 需要在前面添加 “ , ” 以符合json正确格式, 否则报错
i)在项目的根目录创建index.android.js 文件, 可以直接拷贝demo的, 然后根据要求修改
(三)准备工作
i.PS@lz寄语: 工程的大概目录如下:

技术分享

b)在APP 的build.gradle 中添加React Native 依赖
dependencies {
compile "com.facebook.react:react-native:+" // From node_modules.
}
i.PS@lz寄语: 此处会报错

技术分享

技术分享

ii.解决方案如下: 在APP 的build.gradle 内的Android{ }添加
configurations.all {
resolutionStrategy.force ‘com.google.code.findbugs:jsr305:1.3.9‘
}


iii.参考网址 错误Conflict with dependency ‘com.google.code.findbugs:jsr305’
http://blog.csdn.net/qq_23089525/article/details/52777520

c)在项目的build.gradle 文件中, “Allprojects” 代码块中,添加一个maven 依赖的入口
i.PS@lz寄语: 先添加mavenLocal(), 即优先选择本地maven

技术分享

ii.确保依赖路径的正确!以免在 Android Studio 运行Gradle同步构建时抛出 “Failed to resolve: com.facebook.react:react-native:0.x.x" 异常。
d)权限声明, 在AndroidManifest.xml 中声明网络权限
<uses-permission android:name="android.permission.INTERNET" />
如果需要访问 DevSettingsActivity 界面,也需要在AndroidManifest.xml 中声明:
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

(四)添加原生代码
想要通过原生代码调用 React Native ,就像这样,我们需要在一个Activity 中创建一个 ReactRootView 对象,将它关联一个 React application 并设为界面的主视图。
如果你想在安卓5.0以下的系统上运行,请用com.android.support:appcompat 包中的 AppCompatActivity 代替Activity 。
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, "HelloWorld", null);

setContentView(mReactRootView);
}

@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}
如果你的项目名字不是叫“HelloWorld”,则需要将“index.android.js”中的“AppRegistry.registerComponent()”方法中的第一个参数替换为对应的名字。
如果你使用的是 Android Studio , 请用 Alt + Enter 为 MyReactActivity 类导包。当你使用了不止一个 ...facebook... 包时,请谨慎选择要导入的类。
我们需要把 MyReactActivity 的主题设定为Theme.AppCompat.Light.NoActionBar ,因为里面有许多组件都使用了这一主题。
<activity
android:name=".MyReactActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>
A ReactInstanceManager can be shared amongst multiple activities and/or fragments. You will want to make your ownReactFragment or ReactActivity and have a singleton holderthat holds a ReactInstanceManager. When you need theReactInstanceManager (e.g., to hook up theReactInstanceManager to the lifecycle of those Activities or Fragments) use the one provided by the singleton.
Next, we need to pass some activity lifecycle callbacks down to theReactInstanceManager:
@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();
}
}
We also need to pass back button events to React Native:
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
This allows JavaScript to control what happens when the user presses the hardware back button (e.g. to implement navigation). When JavaScript doesn‘t handle a back press, yourinvokeDefaultOnBackPressed method will be called. By default this simply finishes your Activity.
Finally, we need to hook up the dev menu. By default, this is activated by (rage) shaking the device, but this is not very useful in emulators. So we make it show when you press the hardware menu button (useCtrl + M if you‘re using Android Studio emulator):
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
现在activity已就绪,可以运行一些JavaScript代码了。
If your app is targeting the Android API level 23 or greater, make sure you have the overlay permission enabled for the development build. You can check it with Settings.canDrawOverlays(this);. This is required in dev builds because react native development errors must be displayed above all the other windows. Due to the new permissions system introduced in the API level 23, the user needs to approve it. This can be acheived by adding the following code to the Activity file in the onCreate() method. OVERLAY_PERMISSION_REQ_CODE is a field of the class which would be responsible for passing the result back to the Activity.
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);
}
}
Finally, the onActivityResult() method (as shown in the code below) has to be overridden to handle the permission Accepted or Denied cases for consistent UX.
@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...
}
}
}
}
(五)运行你的应用
运行应用首先需要启动开发服务器(Packager)。你只需在项目根目录中执行以下命令即可:
$ npm start
Now build and run your Android app as normal (./gradlew installDebug from command-line; in Android Studio just create debug build as usual).
If you are using Android Studio for your builds and not the Gradle Wrapper directly, make sure you install watchmanbefore running npm start. It will prevent the packager from crashing due to conflicts between Android Studio and the React Native packager.
Once you reach your React-powered activity inside the app, it should load the JavaScript code from the development server and display:

技术分享

 

(六)在Android Studio中打包
你也可以使用Android Studio来打包!You can use Android Studio to create your release builds too! It’s as easy as creating release builds of your previously-existing native Android app. There’s just one additional step, which you’ll have to do before every release build. You need to execute the following to create a React Native bundle, which’ll be included with your native Android app:
$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
Don’t forget to replace the paths with correct ones and create the assets folder if it doesn’t exist!
Now just create a release build of your native app from within Android Studio as usual and you should be good to go!


附件:

Write by lz
2017-04-17

lz的第一个RN项目