美文网首页
Android项目接入ReactNative

Android项目接入ReactNative

作者: 锄禾少年不太帅 | 来源:发表于2019-09-30 16:35 被阅读0次

    Android项目接入ReactNative:

    前言

    1、本次接入的RN版本为0.60.4

    2、android项目gradle编译版本为3.4.1,编译工具buildToolsVersion为28.0.3

    3、如果是原生接入rn,在ios端也需要进行处理,请参考官方资料。

    4、官方文档,点击可以切换android和ios文档,如下图

    官网

    android集成步骤

    第一步:创建项目

    创建RN空项目,把整个android项目复制进rn项目下的android目录下

    第二步:修改项目级build

    修改android项目级别的build.gradle中allprojects下添加代码:

     allprojects {
        repositories {
            google()
            jcenter()
            maven { url "https://jitpack.io" }
            maven {
                // All of React Native (JS, Android binaries) is installed from npm
                url "$rootDir/../node_modules/react-native/android"
            }
        }   
    }
    

    第三步:修改app下build

    在app下的build.gradle的dependencies下添加依赖:

    //指定版本,版本号需要和你package.json中的版本号一致
    implementation "com.facebook.react:react-native:0.59.4" // From node_modules
    

    当rn版本为0.60以上时,可能会报错,

    Manifest merger failed : Attribute application@appComponentFactory value
    

    这时需要把android项目依赖库改成AndroidX库,通过studio一键转换,butterknife记得升级到最新的10.0,不然是无法支持x库,错误如下:

    The given artifact contains a string literal with a package reference 'android.support.v4.content' that cannot be safely rewritten. Libraries using reflection such as annotation processors need to be updated manually to add support for androidx.
    

    第四步:实现application

    程序的Application实现ReactApplication的接口:

    public class MainApplication extends MultiDexApplication implements ReactApplication {
           private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    

    // @Override
    // protected String getJSBundleFile() {
    // return CodePush.getJSBundleFile();
    // }

        @Override
        public boolean getUseDeveloperSupport() {
            LogUtil.e("getUseDeveloperSupport: BuildConfig.DEBUG===" + BuildConfig.DEBUG);
            return BuildConfig.DEBUG;
        }
    
        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
            new RNGestureHandlerPackage()
            //                    new RNGestureHandlerPackage(),
            //                    new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)
            //                    new UpdatePackage(),
            //                    new BlurViewPackage(),
            //                    new OrientationPackage(),
            //                    new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG)
            );
        }
    
    
    
        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    
    };
    
    
    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }
    
    }
    

    第五步:创建入口activity

    创建RN的入口Activity,继承ReactActivity(也可以继承AppCompatActivity,自己实现各种生命周期),如下:

    public class ReactNativeMainActivity  extends ReactActivity {
    
        public static void start(Context context) {
            Intent starter = new Intent(context, ReactNativeMainActivity.class);
            context.startActivity(starter);
        }
    
        @Nullable
        @Override
        protected String getMainComponentName() {
            return "NativeAndroid";
        }
    
        @Override
        protected ReactActivityDelegate createReactActivityDelegate() {
            return new ReactActivityDelegate(this, getMainComponentName()) {
                @Override
                protected ReactRootView createRootView() {
                    return new RNGestureHandlerEnabledRootView(ReactNativeMainActivity.this);
                }
            };
        }
    
    }
    

    注意

    getMainComponentName() 这个方法返回的应该和index.js中返回的appName应该一致,如下:

    AppRegistry.registerComponent('NativeAndroid', () => App);
    

    第六步:

    android studio运行,并在rn项目目录下打开命令窗口开启服务器(指令:npm start),原生使用intent跳转进入rn的activity,等待命令窗口加载JS文件。

    集成完成之后就是一个普通的rn工程,如下图

    rn工程

    接入过程中遇到的问题

    1、打开RN界面运行闪退,报错:

     java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so
    

    github该问题解决地址

    出现此问题基本是集成的0.60.以上的版本导致的,需要修改2个地方:

    项目下的build,需要添加jsc

    maven {
      // Android JSC is installed from npm
      url("$rootDir/../node_modules/jsc-android/dist")
    }
    

    整体如图:

    allprojects {
        repositories {
            mavenLocal()
            maven {
                // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
                url("$rootDir/../node_modules/react-native/android")
            }
            maven {
                // Android JSC is installed from npm
                url("$rootDir/../node_modules/jsc-android/dist")
            }
    
            google()
            jcenter()
        }
    }
    

    app下的build需要添加:

    //在外层添加
    def useIntlJsc = false
    
    //在依赖中添加以下内容
    if (useIntlJsc) {
     implementation 'org.webkit:android-jsc-intl:+'
    } else {
         implementation 'org.webkit:android-jsc:+'
    }
    

    2、react-native run-android命令报错

    :Task 'installDebug' not found in project ':app'.
    

    原因:一般都是多渠道打包导致的

    解决方式:

    第一种:

    react-native run-android --variant ogdfRelease

    react-native run-android --variant assembleDebug

    第二种:

    把app下的build.gradle还原为标准的格式,在build.gradle中不要使用runtime,如:

      productFlavors {
            runtime {
                applicationId "com.df.bwtnative.${station_code}"
                //applicationId "com.op.psit300"
                resValue "string", "app_name", app_name
                resValue "string", "station_code", station_code
            }
            productFlavors.all { flavor ->
                flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
            }
        }
    

    总结

    1、 集成过程总共分为6步(copy原始android项目、修改项目build、修改app的build、修改application、新增rn入口activity)

    2、 android接入rn的老版本是在android工程下创建index.js入口,然后安装node库,整体是以android工程为主导,但rn新版本的接入是把android工程复制到rn下的android目录,整体以rn工程为主导。从开发角度来说,新版本接入更利于android和rn开发的分工。

    3、 集成最新的rn(0.60.4为例)版本需要支持androidX库,所以需要在android工程中修改很多包路径,虽然有studio的一键转换工具,但是从项目安全角度来说,从代码审阅、编译、打包、业务等都需要进行测试一遍,防止隐藏的bug

    4、 原生项目接入rn,android和ios端都需要进行集成,原生代码不共用,但RN代码共用。不确定是否影响ios上架,但单纯的rn项目是可以上架成功。

    相关文章

      网友评论

          本文标题:Android项目接入ReactNative

          本文链接:https://www.haomeiwen.com/subject/lwafyctx.html