Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React-Native集成到现有的安卓项目中(坑死了) #2

Open
ZhangMingZhao1 opened this issue Nov 30, 2018 · 0 comments
Open

React-Native集成到现有的安卓项目中(坑死了) #2

ZhangMingZhao1 opened this issue Nov 30, 2018 · 0 comments

Comments

@ZhangMingZhao1
Copy link
Owner

ZhangMingZhao1 commented Nov 30, 2018

React-Native集成到现有的安卓项目中

RN集成到ios的参见上一篇:#1

毕竟要做跨端,ios调研完了安卓还要再去跑通一下,弄下来感觉安卓比ios更坑一点。RN现在对版本的依赖太固定了,网上问题的教程也太少,版本不一样就不适用了。

1.

按照官网配置相关环境,后面的项目教程就不要跟着官网了,对新手不友好,适合会点原生的开发者,https://reactnative.cn/docs/getting-started/,
安装Android Studio,第一次打开会下载相关的SDK,按照官网教程来,还有JDK,配置环境变量。

用AS创建一个empty activity的项目,

2.

在Android工程中 打开Terminal窗口,npm init,npm install –save react react-native,这样默认下载的最新版,如果出现rn需要哪个版本react支持就install @xx.xx版本的。

就在版本这里卡了很久,我这里之前安装的ios的版本

  "dependencies": {
    "react": "16.0.0",
    "react-native": "0.51.0"
  }

到后面在安卓里增加activity的时候发现和教程的不一样了,AS提示我要重写函数,这个后面说。
所以我现在成功的版本是:

"react": "^16.6.3",
"react-native": "^0.57.7"

3.

在项目的根目录创建.flowconfig文件,该文件的内容可以从Facebook 的GitHub上下载, 查看这里, 将其内容copy进去即可;

4.

接下来在我们项目的根目录下的package.json文件中的scripts节点下添加改句:
"start": "node node_modules/react-native/local-cli/cli.js start"

在我们的项目根目录下添加index.js文件(老rn版本叫index.android.js),该文件即是我们的RN界面,然后在该文件中添加我们React Native界面的代码,例如简单的HelloWorld:
代码如下:

import React, { Component } from 'react';import { Text, AppRegistry } from 'react-native';

export default class App extends Component {
  render() {    return ( <Text>Hello world!</Text>);
  }}
AppRegistry.registerComponent('application', () => App);

5.

在android两个build.gradle里添加

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'(每个人的版本这里可能不一样)
    implementation 'com.facebook.react:react-native:+'
}
allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "$rootDir/node_modules/react-native/android"
        }
    }
}

6.

添加NDK支持,如果不添加这句话的话,可能会造成关于32位和64位SO库混合引入Crash:
i).在App 的build.gradle中的defaultConfig节点下添加如下语句:

ndk {
   abiFilters "armeabi-v7a", "x86"
}
即:
defaultConfig {
        applicationId "com.example.lance.myapplication"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }

ii).然后在我们project下的gradle.properties文件中的末尾添加如下语句:
android.useDeprecatedNdk=true

iii).在App的build.gradle文件的android节点下添加:
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}

7.

完成以上步骤后,React Native就算集成到我们现有的Android项目中,接下来我们用Activity来展示我们的RN:

新版本中的ReactNative只需要自定义一个Activity,并将其集成ReactActivity,实现getMainComponentName()方法,在该方法中返回一开始我们注册的ReactNative的名称即可(即跟我们的index.js中的AppRegistry中的第一个参数相同),在ReactActivity中,已经帮我们实现了ReactRoot与ReactInstanceManager的配置,在之前的版本中,ReactRoot与ReactInstanceManager需要我们自己去写:
完成上面后,我们在android里main里新增一个activity:

package com.example.zhangmingzhao.rnandroid;

import javax.annotation.Nullable;

import com.facebook.react.ReactActivity;

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {        return "application";   //application即注册ReactNative时的名称;
    }
}

这里就是我上面说的遇到的版本的坑,我之前装的ios的版本的rn的时候,重写getMainComponentName后AS还报错提示我要重写一些其他方法,可能就是版本的问题。

8.

接下来创建一个MyApplication,并初始化一个ReactNativeHost,该MyApplication继承Application并实现ReactApplication,在源码loadApp方法时,会将当前的Activity的Application强制转换成ReactApplication:


package com.example.zhangmingzhao.rnandroid;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MyApplication extends Application implements ReactApplication {

    private final ReactNativeHost reactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }
        @Override
         protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(new MainReactPackage());
        }
    };
        @Override
        public ReactNativeHost getReactNativeHost() {
            return reactNativeHost;
        }
        @Override
        public void onCreate() {
            super.onCreate();
            SoLoader.init(this,false);
        }
}

注意有的包option + 回车会提示多个,注意引对。
(这里写的getUseDeveloperSupport好像就是我上部低版本rn下要提示额外重写的方法?)

9.

在原生中加一个按钮,在 MainActivity 添加一个按钮跳转到 MyReactActivity,首先在 app/src/main/res/layout 下的 activity_main.xml 添加一个按钮元素

<Button
	android:id="@+id/btn"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="点击跳转到RN界面"/>

在 MainActivity 里添加点击跳转事件

package com.example.zhangmingzhao.rnandroid;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 点击按钮跳转到 react-native 页面
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,MyReactActivity.class));
            }
        });
    }
}

10.

最后在 app/src/main/AndroidManifest.xml 文件中,添加一些权限,以及声明MainApplication 跟 MyReactActivity

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.zhangmingzhao.rnandroid">

    <uses-permission android:name="android.permission.INTERNET"/>   <!-- 网络权限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- 弹框权限 -->
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/> <!-- 窗体覆盖权限 -->
    <!-- 声明MainApplication -->
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>
        <!-- 声明MyReactActivity -->
        <activity
            android:name=".MyReactActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
        </activity>
        <!-- 声明可以通过晃动手机或者点击Menu菜单打开相关的调试页面 -->
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
    </application>
</manifest>

这种方法下的必须要打包:
我们手动的在app/src/main/目录中添加一个assets目录, 并在该目录下添加一个index.android.bundle文件, 然后手动在该bundle文件中添加内容, 执行以下命令:

react-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/

声明:

  1. --platform : 平台(android/ios)
  2. --dev : 开发模式
  3. --entry-file : 条目文件
  4. --bundle-output : bundle文件生成的目录
  5. --assets-dest : 资源文件生成的目录

ios的npm start启动,安卓模拟器也没识别到,如果是dev模式的话还要另需配置,待我补充,所以总体安卓比ios还是坑多了。

12.

打包后就可以在AS中运行了。注意每次改动AS的配置,都要重新点下Sync
在这里插入图片描述

第一次创建,clone安卓项目也要Sync,还要下载一些东西,用公司内网是真的慢,我自己开的热点。。

13

demo链接:
https://github.com/ZhangMingZhao1/react-native-pratice/tree/master/RNAndroid

参考链接:
http://www.apkbus.com/blog-847095-77211.html
lin-xin/blog#26

总体安卓还是比IOS坑一些,安卓集成RN这个待补充吧。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant