美文网首页
react-native 从0.57.4升级到0.61.0之后遇

react-native 从0.57.4升级到0.61.0之后遇

作者: 程序猿isMe | 来源:发表于2020-01-02 15:04 被阅读0次

    1.react-native 升级到0.61.0,react-native-bottomsheet 库报了

    ERROR: Unable to resolve dependency for ':rnspace@debug/compileClasspath': Failed to transform file 'bottomsheet-1.3.1.aar' to match attributes {artifactType=processed-aar} using transform JetifyTransform
    这个错误
    是由于react-native-bottomsheet也升级到适配androidX的时候,在rnspace库里面的build.gradle -> implementation 'com.cocosw:bottomsheet:1.3.1'对应的版本不对导致的。

    解决办法

    把版本升级到implementation 'com.cocosw:bottomsheet:1.5.0',才适配androidX
    

    2 ERROR: Manifest merger failed with multiple errors, see logs

    看了一下报错是在baidumap里
    解决办法

    1.打开AndroidStudio底部的Terminal, 执行
        ./gradlew processReleaseManifest --stacktrace
         (windows下,应该是gradlew processReleaseManifest --stacktrace)
    看具体报错原因
    
    
    ./gradlew -q app:dependencies   
       查看冲突文件
    
    

    3 错误:android.support.annotation 找不到 react-native-gesture-handler

    react-native-gesture-handler 涉及AndroidX

    解决办法

    "scripts": {
       ...
        "postinstall": "npx jetify"
      },
    
    然后运行一下
    

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

    解决办法在 app/build.gradle中添加如下

    apply plugin: "com.android.application"
    
    project.ext.react = [
        entryFile: "index.js",
        enableHermes: true,  // clean and rebuild if changing
    ]
    
    /**
     * The preferred build flavor of JavaScriptCore.
     *
     * For example, to use the international variant, you can use:
     * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
     *
     * The international variant includes ICU i18n library and necessary data
     * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
     * give correct results when using with locales other than en-US.  Note that
     * this variant is about 6MiB larger per architecture than default.
     */
    def jscFlavor = 'org.webkit:android-jsc:+'
    
    /**
     * Whether to enable the Hermes VM.
     *
     * This should be set on project.ext.react and mirrored here.  If it is not set
     * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
     * and the benefits of using Hermes will therefore be sharply reduced.
     */
    def enableHermes = project.ext.react.get("enableHermes", false);
    
    android {
        compileSdkVersion 28
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    
        defaultConfig {
            applicationId "com.test.lk"
            minSdkVersion 19
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
        }
        signingConfigs {
            debug {
                storeFile file('debug.keystore')
                storePassword 'android'
                keyAlias 'androiddebugkey'
                keyPassword 'android'
            }
        }
        buildTypes {
            debug {
                signingConfig signingConfigs.debug
            }
            release {
                signingConfig signingConfigs.releaseConfig
                minifyEnabled false
                proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            }
        }
      }
    
    dependencies {
        implementation fileTree(dir: "libs", include: ["*.jar"])
        implementation "com.facebook.react:react-native:+"  // From node_modules
    
        if (enableHermes) {
          def hermesPath = "../../node_modules/hermes-engine/android/"
          debugImplementation files(hermesPath + "hermes-debug.aar")
          releaseImplementation files(hermesPath + "hermes-release.aar")
        } else {
          implementation jscFlavor
        }
    }
    

    5 WebView 从react-native 替换成react-native-webview之后postMessage发送不出去

    主要是因为框架修改了,如果您希望在升级时与旧版本保持兼容性,则可以使用注入Javascript支持进行此操作,解决方法来自:
    https://github.com/react-native-community/react-native-webview/releases/tag/v5.0.0

    import React from 'react'
    import {SafeAreaView, Text, TouchableOpacity, View} from 'react-native';
    import {WebView} from 'react-native-webview';
    import {connect} from "react-redux";
    import {mapHosts} from "../../Config/Environment";
    import geolocation from '@react-native-community/geolocation';
    
    
    let location = {};
    
    class SelectMapScreen extends React.Component {
        _watchID;
        static navigationOptions = ({navigation}) => ({
            headerTitle: '位置',
            headerRight: null
        });
    
        componentWillUnmount() {
            geolocation.clearWatch(this._watchID);
        }
    
    
        render() {
            let {dispatch} = this.props;
            let mapURl = mapHosts() + "map.html";
            return (
                <SafeAreaView style={{flex: 1, backgroundColor: '#ffffff'}}>
                    <WebView
                        ref={"webview"}
                        style={[{flex: 1, backgroundColor: '#ffffff'}]}
                        source={{uri: mapURl, headers: { 'Cache-Control':'no-cache'}}}
                        javaScriptEnabled
                        injectedJavaScript={injectedJavascript}
                        onLoad={()=>{
                            this._watchID = geolocation.watchPosition((position) => {
                                let lastPosition = JSON.stringify(position);
                                console.log("initialPosition:" +lastPosition)
                                this.refs.webview.postMessage(JSON.stringify({
                                    cmd: 'location',
                                    data: {lat: position.coords.latitude, lng: position.coords.longitude}
                                }))
                            }, (error) => {
                                alert(error.message)
                            })
                        }}
                        onMessage={(event) => {
                            console.log("---event--", event);
                            const data = JSON.parse(event.nativeEvent.data);
                            console.log("---data--", data);
                            switch (data.cmd) {
                                case "location": {
                                    location = data.data;
                                    break;
                                }
                                default: {
                                    break;
                                }
                            }
    
                        }}
    
                    />
                </SafeAreaView>
    
            )
        }
    }
    
    
    const props = (state) => {
        return {}
    };
    export default connect(props)(SelectMapScreen)
    
    const injectedJavascript = `(function() {
      window.postMessage = function(data) {
        window.ReactNativeWebView.postMessage(data);
      };
    })()`;
    

    5 Error: Unable to resolve module react-navigation/src/NavigationActions from app\Screen\Home\BackLogCaseScreen\Action.js

    这个问题是因为引用的改变
    之前的引用是 import NavigationActions from "react-navigation/src/NavigationActions";
    需要改成 import NavigationActions from "react-navigation";

    6 createBottomTabNavigator() has been moved to react-navigation-tabs

    升级到0.61.0之后引用变了
    之前的引用是 import {createBottomTabNavigator,} from 'react-navigation';
    需要改成 import {createBottomTabNavigator} from 'react-navigation-tabs';

    7 createStackNavigator() has been moved to react-navigation-stack

    升级到0.61.0之后引用变了
    之前的引用是 import {createStackNavigator} from "react-navigation";
    需要改成 import {createStackNavigator} from "react-navigation-stack";

    8 TypeError: Cannot read property 'routeName' of null

    在我这是因为升级后
    const initialState = RootModalNavigation.router.getStateForAction(RootModalNavigation.router.getActionForPathAndParams());这个里面修改了
    得改成const initialState = RootModalNavigation.router.getStateForAction(RootModalNavigation.router.getActionForPathAndParams('Main'));
    'Main'写什么都可以

    9 TypeError: navStateSelector is not a function

    我这是因为
    export const navigationMiddleware = createReactNavigationReduxMiddleware(
    "root",
    state => state.nav,
    );
    改成
    export const navigationMiddleware = createReactNavigationReduxMiddleware(
    state => state.nav,
    "root",
    );

    10 Error: There is no route defined for key LoginScreen.

    错误原因
    const resetAction = StackActions.reset({
                        index: 0,
                        actions: [NavigationActions.navigate({routeName: 'LoginScreen'})]
                    });
                    navigation.dispatch(resetAction);
    
    
    经过github上搜索发现,需要添加  key: undefined,
         const resetAction = StackActions.reset({
                        index: 0,
                        key: undefined,
                        actions: [NavigationActions.navigate({routeName: 'LoginScreen'})]
                    });
                    navigation.dispatch(resetAction);
    

    11 redux-persist failed to create sync storage. falling back to noop storage.

    是在redux的存储有了变化
    之前是:

    import {applyMiddleware, createStore} from 'redux';
    import thunkMiddleware from 'redux-thunk'
    import {persistCombineReducers, persistStore} from 'redux-persist'
    import storage from 'redux-persist/es/storage'
    import {navigationMiddleware} from "../Navigation/Reducer";
    import {rootReducers} from "../Reducer/RootReducer";
    import {composeWithDevTools} from 'redux-devtools-extension';
    
    
    const middleWares = [
        navigationMiddleware,
        thunkMiddleware
    ];
    
    const config = {
        key: 'root',
        storage,
        whitelist: ['onSaveLoginInfo','onRequestStaticHeader'],
        debug: false
    };
    
    const reducers = persistCombineReducers(config, rootReducers);
    const enhances = [applyMiddleware(...middleWares)];
    let store;
    
    export const configState = (initialState) => {
        store = createStore(reducers, initialState, composeWithDevTools(...enhances));
    
        persistStore(store);
        return store
    };
    
    export const getStore = () => {
    
        return store;
    };
    
    

    我们需要将import storage from 'redux-persist/es/storage'去掉,换成import AsyncStorage from '@react-native-community/async-storage'; 最终是

    import {applyMiddleware, createStore} from 'redux';
    import thunkMiddleware from 'redux-thunk'
    import {persistCombineReducers, persistStore} from 'redux-persist'
    import AsyncStorage from '@react-native-community/async-storage';
    import {navigationMiddleware} from "../Navigation/Reducer";
    import {rootReducers} from "../Reducer/RootReducer";
    import {composeWithDevTools} from 'redux-devtools-extension';
    
    
    const middleWares = [
        navigationMiddleware,
        thunkMiddleware
    ];
    
    const config = {
        key: 'root',
        storage: AsyncStorage,
        whitelist: ['onSaveLoginInfo','onRequestStaticHeader'],
        debug: false
    };
    
    const reducers = persistCombineReducers(config, rootReducers);
    const enhances = [applyMiddleware(...middleWares)];
    let store;
    
    export const configState = (initialState) => {
        store = createStore(reducers, initialState, composeWithDevTools(...enhances));
    
        persistStore(store);
        return store
    };
    
    export const getStore = () => {
    
        return store;
    };
    

    12 Invariant Violation: Could not find "store" in the context of "Connect(TabBarComponent)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(TabBarComponent) in connect options.

    是因为之前的connect 是 import connect from "react-redux/es/connect/connect";引用的,所以报错
    现在需要改成import {connect} from "react-redux";

    13 Invariant Violation: [715,"RCTView",181,{"width":0,"height":"<<NaN>>","backgroundColor":0}] is not usable as a native method argument

    是因为react-native-page-scrollview
    在更新到新版本后不适配,可以参考https://github.com/geek-prince/react-native-page-scrollview/issues/9

    14 WebView has been removed from React Native. It can now be installed and imported from 'react-native-webview' instead of 'react-native'.

    在升级到0.61.0后webview被拆分出去了,引用不能用import {WebView} from "react-native";
    修改成 import {WebView} from 'react-native-webview';

    15 权限

    import {request, PERMISSIONS, RESULTS} from 'react-native-permissions';
    import { Platform } from 'react-native'
    
    export const PermissionType = {
        Photo: Platform.OS === 'android' ? PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE : PERMISSIONS.IOS.PHOTO_LIBRARY, // 相册
        Camera: Platform.OS === 'android' ? PERMISSIONS.ANDROID.CAMERA : PERMISSIONS.IOS.CAMERA, // 相机
        Location: Platform.OS === 'android' ? PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION : PERMISSIONS.IOS.LOCATION_WHEN_IN_USE, // 定位
        Storage:  Platform.OS === 'android' ? PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE : "",           // 读写权限
    
        Notification: 'notification', // 推送
        CallPhone: Platform.OS === 'android' ? PERMISSIONS.ANDROID.CALL_PHONE : ""
    };
    
    export const CheckPermission = (type) => new Promise(function (resolve, reject) {
        request(type)
            .then(result => {
                console.log("--------", result)
                switch (result) {
                    case RESULTS.UNAVAILABLE:
                        console.log('This feature is not available (on this device / in this context)');
                        break;
                    case RESULTS.DENIED:
                        console.log('The permission has not been requested / is denied but requestable');
                        reject(new Error(message(type)));
                        break;
                    case RESULTS.GRANTED:     // 授予
                        console.log('The permission is granted');
                        resolve(result);
                        break;
                    case RESULTS.BLOCKED:
                        console.log('The permission is denied and not requestable anymore');
                        reject(new Error(message(type)));
                        break;
                }
            })
            .catch(err => {
                reject(err);
            })
    });
    
    export const CheckMultiple = () => new Promise(function (resolve, reject) {
        let permission1 = CheckPermission(PermissionType.CallPhone);
        let permission2 = CheckPermission(PermissionType.Location);
        let permission3 = CheckPermission(PermissionType.Storage);
        Promise.all([permission1,permission2,permission3]).then((res)=>{
            resolve(res)
        }).catch(e=>{
            reject(new Error(message(PermissionType.CallPhone)+message(PermissionType.Location)+message(PermissionType.Storage)));
        })
    });
    
    
    const message = (type) => {
        switch (type) {
            case PermissionType.Photo:
                return '应用需要使用您的相册,请前往设置去开启相册权限';
            case PermissionType.Camera:
                return '应用需要使用您的相机,请前往设置去开启相机权限';
            case PermissionType.Location:
                return '应用需要使用您的位置,请前往设置去开启定位权限';
            case PermissionType.Storage:
                return '应用需要使用您的读写权限,请前往设置去开启读写权限';
            default:
                return null;
        }
    };
    

    16 解决Android Studio提示:安装包有异常,无法安装

    问题描述:在使用Android Studio运行程序时,手机为oppo手机,遇到安装失败,在其他手机上安装正常,经查询后发现Android Studio 3.0会在debug apk的manifest文件application标签里自动添加 android:testOnly="true"属性。
    该属性导致在IDE中使用Run生成的apk在大部分手机上只能用adb install -t 来安装。
    这种apk在oppo手机上甚至安装不了。

    解决办法是

    在gradle.properties 文件中添加如下指令:

    android.injected.testOnly=false
    

    在运行安装,好使

    17 程序正常安装debug模式,服务的ip和端口号输入后却链接不上服务

    Screenshot_2020-04-10-16-35-08-40.png

    原来9.0系统已经默认不支持http请求了,谷歌默认要求链接是加密链接了
    解决方案:
    在res目录添加一个xml文件夹,新建一个network_security_config.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!--Android 9.0 https请求适配-->
    <network-security-config>
    <base-config cleartextTrafficPermitted="true" />
    </network-security-config>
    

    然后在AndroidManifest.xml清单文件上加入

     <application
            android:name=""
            android:icon="@drawable/logo_icon"
            android:label="@string/app_name"
            android:roundIcon="@drawable/logo_icon"
            android:theme="@style/AppTheme"
            android:networkSecurityConfig="@xml/network_security_config"
           > 
     </application>
    

    由于工作原因只记录了,其中一部分的问题,其他的根据提示相信各位也能很好的解决,谢谢大家!!

    相关文章

      网友评论

          本文标题:react-native 从0.57.4升级到0.61.0之后遇

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