react-native 从0.57.4升级到0.61.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>
由于工作原因只记录了,其中一部分的问题,其他的根据提示相信各位也能很好的解决,谢谢大家!!