【问题标题】:Lost connection to device. Exited (sigterm) - Flutter Crash失去与设备的连接。退出 (sigterm) - Flutter Crash
【发布时间】:2021-05-02 18:05:37
【问题描述】:

我的 Flutter 应用在​​加载时崩溃

它运行一个 FutureBuilder,我相信这就是问题所在。

我的应用进行 API 调用并将数据返回到地图标记。

当我让 FutureBuilder 返回一个列表视图时,它工作正常。

但是,当我将其更改为返回包含我的 Map SDK 和按钮以调用 API 的堆栈时,它会在启动时崩溃。

相关代码如下,谢谢!

class HomePage extends StatefulWidget { 

  @override
  _HomePageState createState() => _HomePageState();
}
 

class _HomePageState extends State<HomePage> {
  Future<Stations> stations;
  BuildContext _context;
  MapMarkerExample _mapMarkerExample; 
  


  @override
  void initState() {
   stations = API_Call().fetchStations(); 
   super.initState();
  }
  


  @override
  Widget build(BuildContext context) {
    return Scaffold(
         appBar: AppBar(
          title: Text('Example 1'),
        ),
        
      body: Container(
 
        child: FutureBuilder<Stations>(
          future: stations,
       
            builder: (context, snapshot) {
     
        if (snapshot.hasError) {
          return Text("Error");
        }
  
        if (snapshot.connectionState == ConnectionState.done) {
          return 
          
          Stack(
          children: [
            HereMap(onMapCreated: _onMapCreated),
          

            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    button('Stations Near Me', _anchoredMapMarkersButtonClicked),
                    button('Clear', _clearButtonClicked),
                  ],
                ),
              ],
            ),
          ],
            );
        }
        
        return Text("Loading");
           
           

            }
        ) 
      )
        );
           }

api_call.dart

class API_Call {

Future<Stations> fetchStations() async {
    var client = http.Client();

      final response = await client.get(
      'https://transit.hereapi.com/v8/stations?in=x,-x&return=transport&apiKey=API_KEY');
   
    if (response.statusCode == 200) {
    return Stations.fromJson(jsonDecode(response.body)); 
  } else {
    throw Exception('Failed to load stations');
  }
    }
    }

api_manager.dart

 typedef ShowDialogFunction = void Function(String title, String message);

 class MapMarkerExample{
 
    
  void showAnchoredMapMarkers() { 
  print('step5');
  
   GeoCoordinates geoCoordinates = _callGeoCoordinates();
           // use the coords .. to add a marker
           _addCircleMapMarker(geoCoordinates, 0);
           _addPOIMapMarker(geoCoordinates, 1);
           print('step6');
  } 

    
 GeoCoordinates _callGeoCoordinates() {
   print('step7');
   var stations;

   Future<Stations> fetchStations() async {
       stations = await API_Call().fetchStations(); 
       for (Station stations in stations) {
           GeoCoordinates geoCoordinates = GeoCoordinates (stations.place.location.lat, stations.place.location.lng);
           // use the coords .. to add a marker
           _addCircleMapMarker(geoCoordinates, 0);
           _addPOIMapMarker(geoCoordinates, 1);
           } 
        }
    }


  HereMapController _hereMapController;
  List<MapMarker> _mapMarkerList = [];
  MapImage _poiMapImage;
  MapImage _circleMapImage;
  ShowDialogFunction _showDialog;
  List<MapMarker3D> _mapMarker3DList = [];
   
   MapMarkerExample(ShowDialogFunction showDialogCallback, HereMapController hereMapController) {
    _showDialog = showDialogCallback;
    _hereMapController = hereMapController;

    double distanceToEarthInMeters = 8000;
    _hereMapController.camera.lookAtPointWithDistance(
      GeoCoordinates(x, -x), distanceToEarthInMeters);

    // Setting a tap handler to pick markers from map.
    _setTapGestureHandler();

    _showDialog("Note", "Tap markers for more.");
    }




  void clearMap() {
    for (var mapMarker in _mapMarkerList) {
      _hereMapController.mapScene.removeMapMarker(mapMarker);
    }
    _mapMarkerList.clear();

    for (var mapMarker3D in _mapMarker3DList) {
      _hereMapController.mapScene.removeMapMarker3d(mapMarker3D);
    }
    _mapMarker3DList.clear();
  }

  Future<void> _addPOIMapMarker(GeoCoordinates geoCoordinates, int drawOrder) async {
    // Reuse existing MapImage for new map markers.
    if (_poiMapImage == null) {
      Uint8List imagePixelData = await _loadFileAsUint8List('assets/poi.png');
      _poiMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
    }

    Anchor2D anchor2D = Anchor2D.withHorizontalAndVertical(0.5, 1);

    MapMarker mapMarker = MapMarker.withAnchor(geoCoordinates, _poiMapImage, anchor2D);
    mapMarker.drawOrder = drawOrder;

    Metadata metadata = new Metadata();
    metadata.setString("key_poi", "Next Departures");
    mapMarker.metadata = metadata;

    _hereMapController.mapScene.addMapMarker(mapMarker);
    _mapMarkerList.add(mapMarker);
  }

  Future<void> _addCircleMapMarker(GeoCoordinates geoCoordinates, int drawOrder) async {
    // Reuse existing MapImage for new map markers.
    if (_circleMapImage == null) {
      Uint8List imagePixelData = await _loadFileAsUint8List('assets/circle.png');
      _circleMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
    }
    
    MapMarker mapMarker = MapMarker(geoCoordinates, _circleMapImage);
    mapMarker.drawOrder = drawOrder;

    _hereMapController.mapScene.addMapMarker(mapMarker);
    _mapMarkerList.add(mapMarker);
  }

  Future<Uint8List> _loadFileAsUint8List(String assetPathToFile) async {
    // The path refers to the assets directory as specified in pubspec.yaml.
    ByteData fileData = await rootBundle.load(assetPathToFile);
    return Uint8List.view(fileData.buffer);
  }

  void _setTapGestureHandler() {
    _hereMapController.gestures.tapListener = TapListener.fromLambdas(lambda_onTap: (Point2D touchPoint) {
      _pickMapMarker(touchPoint);
    });
  }

  void _pickMapMarker(Point2D touchPoint) {
    double radiusInPixel = 2;
    _hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
      // Note that 3D map markers can't be picked yet. Only marker, polgon and polyline map items are pickable.
      List<MapMarker> mapMarkerList = pickMapItemsResult.markers;
      if (mapMarkerList.length == 0) {
        print("No map markers found.");
        return;
      }
    });
  }
    }

【问题讨论】:

  • 您是否在 iOS 上添加了 Google 地图 api 密钥?这很可能是您崩溃的原因。
  • @HuthaifaMuayyad 这不是 Google 地图,而是 HERE 地图。我实际上已删除 API KEY 以保护隐私 - API 密钥已完全输入我的项目中
  • 我不是指调用的API密钥,但是渲染地图也需要密钥,并且该密钥是通过XCODE添加到info.plist的。 flutter run -v 的输出是什么?它应该显示详细的输出,说明究竟是什么导致了崩溃。如果您可以将其添加到您的帖子中,那会有所帮助。
  • @HuthaifaMuayyad 已添加反馈
  • end of dumpstacktrace 之前是什么?有人说 map_marker 未来不完整。请分享之前的内容。

标签: ios flutter dart maps


【解决方案1】:

api_manager.dart 中,这看起来很可疑,并且您没有从该函数返回任何内容,这也可以解释错误说future not complete

 Future<Stations> fetchStations() async {
   stations = await API_Call().fetchStations(); 
   
       for (Station stations in stations) {
           GeoCoordinates geoCoordinates = GeoCoordinates (stations.place.location.lat, stations.place.location.lng);
           // use the coords .. to add a marker
           _addPOIMapMarker(geoCoordinates, 1);
           }   

          // GeoCoordinates geoCoordinates = stations.coordinates;
          // _addPOIMapMarker(geoCoordinates, 1);
 
    }
 }

你必须从中返回一个Stations对象,在你的for循环之后尝试return stations;之类的东西,它可以解决你的问题,如果错误发生变化,这也是一个好的开始。

还将您在未来构建器中的行更改为:

if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) 

同时,删除此_setTapGestureHandler()。崩溃很可能是内存泄漏引起的,从贴出的代码来看,可以用listeners来解释。

【讨论】:

  • 感谢您的回复 - 我尝试在我的 for{} 之后添加它,但在我的搜索中仍然返回了 future not complete。我的api_call.dart 中有一个return stations,for 循环只是添加带有拉/拉的 POI 标记
  • 在调试模式下运行您的应用程序,并注意它崩溃的位置\设置断点。然后逐渐步入断点。
  • 我在答案中添加了可以缩小范围的信息,试一试。
  • 我的Futurevoid 内部调用是否会导致Future 的问题仍未返回?
  • 可能,您是否尝试过我添加到答案中的步骤?我们必须确切知道是什么导致它崩溃,然后我们才能修复它
猜你喜欢
  • 1970-01-01
  • 2021-04-18
  • 2019-10-22
  • 2021-02-04
  • 2021-05-25
  • 2022-01-10
  • 2019-12-05
  • 2020-02-12
  • 2020-08-21
相关资源
最近更新 更多