美文网首页React Native@IT·互联网React Native开发
Native项目迁入React-Native过程中遇到的坑(0.

Native项目迁入React-Native过程中遇到的坑(0.

作者: 王亟亟 | 来源:发表于2017-04-27 15:12 被阅读263次

    转载请注明出处王亟亟的大牛之路

    最近都在忙着搭架子,找框架,谈需求和开会。甚至都没有时间好好装逼,昨天帮安卓的小伙把项目从安卓整体迁移到了RN的项目下面,过程中遇到很多不可描述的坑,这里给大家分享下经验

    先安利,安卓收纳库:https://github.com/ddwhan0123/Useful-Open-Source-Android

    React-Native收纳库:https://github.com/ddwhan0123/Useful-Open-Source-React-Native


    由来

    项目刚开始的阶段我还不在场(最初的app完全没有RN/Weex的相关模块),然后在我到岗后产品发现了,React-Native的“美好“,决定把原有的项目重构,7成的业务量迁移到React-Native模块。

    人手问题

    重构开始前的人员配比
    Android: 2人
    iOS: 4人
    前端:1名(会Vue,会一点React,完全没摸过RN的)

    过去一个月后
    Android: 3人(有一个能写点简单RN页面)
    iOS: 3人(原有的一个被我拽去强行干RN了)
    前端:3(会React/Vue不会RN)+2(RN选手,会用Redux等第三方RN库)+1(iOS被强拽的小伙)


    模块区分

    在分页面之初和产品砍了砍准则
    (很多人觉得奇怪,既然如此为什么不用纯RN?我的答案是,你不在位置上你不能理解,纯原生的人难道就待机?)

    • 变动不大的用Native
    • 跟硬件相关的模块用Native
    • 逻辑复杂但是页面本身不复杂的用RN(这条被产品一个巴掌拍回了,他们不管实现难度)
    • 需要热更的用RN
    • 其他省略

    然后原生只剩下以下模块

    • 登陆/注册
    • 支付页面
    • WebView相关页面(这块你懂的,强行拽来的)

    迁移iOS

    建完项目后先是拽iOS部分

    这里写图片描述

    基本没有遇到任何阻力,10分钟(分支选择耗费了几分钟)就整完了简单的插了个RN页面,跑起来无异常,iOS Over


    迁移Android

    android长这样(自己项目各有差异,这个无所谓了,反正改安卓,改的不是目录是Gradle配置)

    这里写图片描述

    1.首先是查看授权,有就算了,没有就加

       <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
        <uses-permission android:name="android.permission.INTERNET" />
    

    两个必要的授权加一下,一个是弹窗,一个是网络

    2.项目文件的dependencies里加上RN的依赖

     compile 'com.facebook.react:react-native:+'  // From node_modules
    

    3.android.gradle里添加本地Maven的依赖

    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"
            }
    }
    

    你自己的项目应该还会有jcenter()和公网maven{}相关内容

    4.添加摇一摇的Activity

         <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    

    配置级别的内容已经贴完了

    5.接下来是测试代码(这部分内容在之前的互相跳转里出现过)

    首先要建一个 ReactActivity

    import com.facebook.react.ReactActivity;
    
    import javax.annotation.Nullable;
    
    public class RNActivity extends ReactActivity {
        @Nullable
        @Override
        protected String getMainComponentName() {
            return "统一的控件名";
        }
    }
    
    

    然后建一个测试用的Module

    public class IntentModule extends ReactContextBaseJavaModule {
        public IntentModule(ReactApplicationContext reactContext) {
            super(reactContext);
        }
    
        @Override
        public String getName() {
            return "IntentModule";
        }
    
        @ReactMethod
        public void getDataFromIntent(Callback success, Callback error) {
            try {
                Activity currentActivity = getCurrentActivity();
                String result = currentActivity.getIntent().getStringExtra("result");//会有对应数据放入
                if (!TextUtils.isEmpty(result)) {
                    success.invoke(result);
                }
            } catch (Exception ex) {
                error.invoke(ex.getMessage());
            }
        }
    }
    
    

    添加注册到Application里去的Package

    public class MyReactPackage implements ReactPackage {
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            return Arrays.<NativeModule>asList(new IntentModule(reactContext));
        }
    
        @Override
        public List<Class<? extends JavaScriptModule>> createJSModules() {
            return Collections.emptyList();
        }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    }
    

    在Application里注册关联

    
    public class App extends Application implements ReactApplication {
    
        @Override
        public void onCreate() {
            super.onCreate();
            SoLoader.init(this, /* native exopackage */ false);
        }
    
        @Override
        public ReactNativeHost getReactNativeHost() {
            return mReactNativeHost;
        }
    
        private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
            @Override
            public boolean getUseDeveloperSupport() {
                return BuildConfig.DEBUG;
            }
    
            @Override
            protected List<ReactPackage> getPackages() {
                return Arrays.<ReactPackage>asList(
                        new MainReactPackage(),new MyReactPackage()
                );
            }
        };
    }
    
    

    改完之后上传 git


    尝试性调试

    git clone git@11.11.111.111:aaa-aaaa/RN_App.git (地址你懂的)
    
    cd RN_App
    
    npm install
    
    react-native start
    
    curl "http://localhost:8081/index.android.bundle?platform=android" -o "android/app/src/main/assets/index.android.bundle"
    
    react-native run-android
    

    在ok的情况下,跳转完会长这样

    这里写图片描述

    看上去是不太复杂但是,实质上遇到很多操蛋的问题,我在这里给大家罗列下


    坑1: okhttp3.6那些事

    这里写图片描述

    RN 0.43用的是ok http3.4.1
    但是项目中用到了3.6.0
    然后在websocket api的地方有兼容问题(当时心里简直操蛋)
    解决方法

    主项目添加兼容的dependencies设置

    configurations.all { resolutionStrategy.force 'com.squareup.okhttp3:okhttp:3.4.1' }
    

    相关文章:https://github.com/facebook/react-native/issues/11680


    坑2 js bundle打不进项目,也就是 Js Server跑起来了,react-native run-android包是打了,但是他喵的js没打进去(我也不知道怎么日狗了)

    方法1,打本地包(offline姿势)

    react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
    

    路径根据你的具体项目而定

    方法2,打js服务的包,也就是我上面提到的

    curl "http://localhost:8081/index.android.bundle?platform=android" -o "android/app/src/main/assets/index.android.bundle"
    

    结果会打一个bundle出来


    这里写图片描述

    坑3 摇了没反应

    这个问题我还没解决,或者说没时间解决,交给给小伙们去干了(一般是手机弹窗的授权问题相关)


    坑4 执行 react-native run-android 安装成功后 Activity class does not exist

    这里写图片描述
    已知的错误场景:http://stackoverflow.com/questions/35131769/error-type-3-activity-class-com-awesome-project-com-awesome-project-mainactiv

    具体的错误来源于项目的MainActivity不在根目录。

    方法1,迁移MainActivity.class
    不解释了,字面意思

    方法2,改运行的脚本

    其实也就是修改runAndroid.js

    他在node_modules.react-native/local-cli/runAndroid/runAndroid.js

    修改方式也很简单,path肯定是拼接的,找到拼的代码改了就行


    这里写图片描述

    最佳解决指南:https://github.com/facebook/react-native/issues/5546

    相关文章

      网友评论

        本文标题:Native项目迁入React-Native过程中遇到的坑(0.

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