这几天开始根据react-native中文网进行react-native+android studio开发,但是在看了官网之后,你会发现项目并跑不起来,辗转几次,翻看别人博客,多是官网的照搬,在一个朋友的帮助下完成react-native的嵌入原生应用.
图一
图二
点击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将会在后续博文中总结,欢迎提意见,关注;期待一起进步