You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native @rnmapbox/maps搭配react-navigation安卓跳转崩溃

@rnmapbox/maps 跨页面导航Android端崩溃异常

问题现象

  • 使用@rnmapbox/maps渲染地图页面时,执行跨页面跳转操作会先触发应用卡顿,随后直接崩溃
  • 移除<MapboxGL.MapView>标签内部所有子组件后,导航功能恢复正常,确认异常与Mapbox地图组件直接相关
  • 项目使用@react-navigation/native + @react-navigation/native-stack作为导航方案,异常仅在Android平台复现,iOS端全流程运行无任何问题
  • 复现录屏:问题复现录屏

项目核心代码

App.js

import React from 'react';
import MapScreen from './src/screens/MapScreen';
import PlaceDetailsScreen from './src/screens/PlaceDetailsScreen';
import VideoPlayerScreen from './src/screens/VideoPlayerScreen';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {GestureHandlerRootView} from 'react-native-gesture-handler';

function App() {
  const Stack = createNativeStackNavigator();
  return (
    <SafeAreaProvider>
      <GestureHandlerRootView style={{flex: 1}}>
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen
              name="Map"
              component={MapScreen}
              options={{headerShown: false}}
            />
            <Stack.Group>
              <Stack.Screen name="Details" component={PlaceDetailsScreen} />
              <Stack.Screen
                name="VideoPlayer"
                component={VideoPlayerScreen}
                options={{headerShown: false}}
              />
            </Stack.Group>
          </Stack.Navigator>
        </NavigationContainer>
      </GestureHandlerRootView>
    </SafeAreaProvider>
  );
}

export default App;

MapScreen.js

import React, {useState, useRef, useMemo, useCallback, useEffect} from 'react';
import {View, Text, PermissionsAndroid, Platform} from 'react-native';
import MapboxGL from '@rnmapbox/maps';
import BottomSheet, {BottomSheetScrollView} from '@gorhom/bottom-sheet';
import Styles from '../../Styles';
import PlaceBtn from '../components/PlaceBtn/PlaceBtn';
import IconPin from './../assets/icons/icon-locationPin.svg';
MapboxGL.setAccessToken(
  'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
);

function MapScreen({navigation}) {
  const [hasGeolocPermission, setHasGeolocPermission] = useState(false);
  const [currentRegion, setCurrentRegion] = useState([4.824, 45.76]); // 经度, 纬度
  const [userLocation, setUserLocation] = useState();
  const [nearestPoints, setNearestPoints] = useState([]);
  const markers = require('../data/markers.json');
  const route = require('../data/route.json');
  const routeLine = {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        properties: {},
        geometry: {
          type: 'LineString',
          coordinates: route.points,
        },
      },
    ],
  };

  const bottomSheetRef = useRef(null);
  const snapPoints = useMemo(() => ['13%', '75%', '100%'], []);

  const handleSheetChanges = useCallback(index => {
    console.log('handleSheetChanges', index);
  }, []);

  const requestLocationPermission = async () => {
    if (Platform.OS === 'android') {
      try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
          console.log('location uses is granted');
          setHasGeolocPermission(true);
        } else {
          console.log(granted);
          console.log('location access denied');
        }
      } catch (error) {
        console.warn('error while request location : ', error);
      }
    }
  };

  useEffect(() => {
    requestLocationPermission();
  }, []);
  return (
    <View style={Styles.container}>
      <MapboxGL.MapView style={Styles.map} scaleBarEnabled={false}>
        <MapboxGL.UserLocation
          animated
          showsUserHeadingIndicator
          minDisplacement={1}
          onUpdate={position => {
            console.log('position : ', position);
          }}
        />
        <MapboxGL.Camera centerCoordinate={currentRegion} zoomLevel={14} />
        {markers.map((marker, index) => {
          if (marker.category === 'introduction') {
            console.log('intro');
          } else {
            return (
              <MapboxGL.PointAnnotation
                key={index}
                id={marker.id + ''}
                coordinate={[marker.longitude, marker.latitude]}>
                <IconPin width={35} height={35} fill={'#00c0aa'} />
              </MapboxGL.PointAnnotation>
            );
          }
        })}
        <MapboxGL.ShapeSource id="line1" shape={routeLine}>
          <MapboxGL.LineLayer
            id="linelayer1"
            style={{lineColor: 'red', lineWidth: 5}}
          />
        </MapboxGL.ShapeSource>
      </MapboxGL.MapView>
      <BottomSheet
        ref={bottomSheetRef}
        handleIndicatorStyle={Styles.handleIndicator}
        index={0}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}>
        <View style={Styles.bottomSheetContent}>
          <Text style={Styles.bottomSheetTitle}>{route.name}</Text>
          <BottomSheetScrollView>
            {markers.map((place, index) => {
              return (
                <PlaceBtn
                  place={place}
                  navigation={navigation}
                  //isNear={nearestPoints.includes(place.id)}
                />
              );
            })}
          </BottomSheetScrollView>
        </View>
      </BottomSheet>
    </View>
  );
}

export default MapScreen;

PlaceDetailsScreen.js

import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';

function PlaceDetailsScreen({navigation}) {
  return (
    <>
      <TouchableOpacity
        style={{backgroundColor: '#00FF00'}}
        onPress={() => navigation.navigate('Map')}>
        <Text>返回地图页</Text>
      </TouchableOpacity>
      <TouchableOpacity
        style={{backgroundColor: '#00FF00'}}
        onPress={() => navigation.navigate('VideoPlayer')}>
        <Text>跳转视频播放页</Text>
      </TouchableOpacity>
    </>
  );
}

内容的提问来源于stack exchange,提问作者K1000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:21:33