zoukankan      html  css  js  c++  java
  • React-Native集成到现有的安卓项目中(坑死了)

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

    RN集成到ios的参见上一篇:https://github.com/ZhangMingZhao1/MingZhao-s-blog/issues/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

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

  • 相关阅读:
    重建二叉树
    数值的整数次方
    二维数组查找
    二进制中1的个数
    LRU算法的精简实现(基于Java)
    华为18.9.5校招笔试题AK
    避免反射和序列化来破坏单例
    Markdown图片存储解决方法-利用阿里云OSS
    基于Java反射的map自动装配JavaBean工具类设计
    多态与类初始化的底层原理
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/10044817.html
Copyright © 2011-2022 走看看