Flutter:ArcGIS 地图视图作为平台视图在 Android 上崩溃

问题描述 投票:0回答:1

我正在尝试在 Flutter 应用程序中托管来自 ArcGIS Maps SDK for Kotlin v200.1 的本机 MapView

这是我的

main.dart
文件,它仅在支架内显示自定义
MapView
小部件:

// lib/main.dart
import 'package:flutter/material.dart';
import 'map_view.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('ArcGIS Map View'),
        ),
        body: const Center(
          child: MapView()
        ),
      ),
    );
  }
}

MapView
小部件看起来像这样:

// lib/map_view.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class MapView extends StatelessWidget {
  const MapView({super.key});

  @override
  Widget build(BuildContext context) {
    if (defaultTargetPlatform == TargetPlatform.iOS) {
      return const UiKitView(viewType: _viewType);
    } else if (defaultTargetPlatform == TargetPlatform.android) {
      return const AndroidView(viewType: _viewType);
    } else {
      throw UnsupportedError('Platform not supported');
    }
  }

  static const _viewType = 'mapView';
}

在 Android 端,我尝试创建 ArcGIS 地图视图作为

PlatformView
:

的一部分
// android/app/src/main/kotlin/com/example/test/NativeView.kt
package com.example.test

import android.content.Context
import android.view.View

import io.flutter.plugin.platform.PlatformView

import com.arcgismaps.ApiKey
import com.arcgismaps.ArcGISEnvironment
import com.arcgismaps.mapping.ArcGISMap
import com.arcgismaps.mapping.BasemapStyle
import com.arcgismaps.mapping.Viewpoint
import com.arcgismaps.mapping.view.MapView

internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?) : PlatformView {
    private val mapView: MapView

    init {
        ArcGISEnvironment.apiKey = ApiKey.create("<hidden>")

        mapView = MapView(context)
        mapView.map = ArcGISMap(BasemapStyle.ArcGISTopographic)
        mapView.setViewpoint(Viewpoint(34.0270, -118.8050, 72000.0))
    }

    override fun getView(): View {
        return mapView
    }

    override fun dispose() {}
}

NativeView
NativeViewFactory
实例化,如 Flutter 文档中所述(托管原生 Android 视图)。

在 Android 模拟器中运行 Flutter 应用程序时,它在启动时崩溃,并出现异常,提示“lateinit property lifeCycleOwner has not beinitialed”:

A Dart VM Service on sdk gphone64 x86 64 is available at: http://127.0.0.1:65061/zcoQFFeeeZk=/
The Flutter DevTools debugger and profiler on sdk gphone64 x86 64 is available at:
http://127.0.0.1:9102?uri=http://127.0.0.1:65061/zcoQFFeeeZk=/
I/PlatformViewsController(10555): Hosting view in view hierarchy for platform view: 0
I/Choreographer(10555): Skipped 62 frames!  The application may be doing too much work on its main thread.
E/FrameEvents(10555): updateAcquireFence: Did not find frame.
W/Parcel  (10555): Expecting binder but got null!
I/TextureView(10555): onSurfaceTextureAvailable
D/AndroidRuntime(10555): Shutting down VM
E/FrameEvents(10555): updateAcquireFence: Did not find frame.
E/AndroidRuntime(10555): FATAL EXCEPTION: main
E/AndroidRuntime(10555): Process: com.example.test, PID: 10555
E/AndroidRuntime(10555): kotlin.UninitializedPropertyAccessException: lateinit property lifeCycleOwner has not been initialized
E/AndroidRuntime(10555):        at com.arcgismaps.mapping.view.GeoView.getLifeCycleOwner$api_release(GeoView.kt:110)
E/AndroidRuntime(10555):        at com.arcgismaps.mapping.view.GeoView$RenderingThread.onSurfaceTextureAvailable(GeoView.kt:1630)
E/AndroidRuntime(10555):        at android.view.TextureView.getTextureLayer(TextureView.java:466)
E/AndroidRuntime(10555):        at android.view.TextureView.draw(TextureView.java:415)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22061)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22052)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:23197)
E/AndroidRuntime(10555):        at io.flutter.plugin.platform.PlatformViewWrapper.draw(PlatformViewWrapper.java:305)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22061)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22052)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22052)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22052)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:22925)
E/AndroidRuntime(10555):        at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
E/AndroidRuntime(10555):        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
E/AndroidRuntime(10555):        at android.view.View.draw(View.java:23197)
E/AndroidRuntime(10555):        at com.android.internal.policy.DecorView.draw(DecorView.java:821)
E/AndroidRuntime(10555):        at android.view.View.updateDisplayListIfDirty(View.java:22061)
E/AndroidRuntime(10555):        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:689)
E/AndroidRuntime(10555):        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:695)
E/AndroidRuntime(10555):        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:793)
E/AndroidRuntime(10555):        at android.view.ViewRootImpl.draw(ViewRootImpl.java:4670)
E/AndroidRuntime(10555):        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4381)
E/AndroidRuntime(10555):        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3600)
E/AndroidRuntime(10555):        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2328)
E/AndroidRuntime(10555):        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9087)
E/AndroidRuntime(10555):        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231)
E/AndroidRuntime(10555):        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
E/AndroidRuntime(10555):        at android.view.Choreographer.doCallbacks(Choreographer.java:899)
E/AndroidRuntime(10555):        at android.view.Choreographer.doFrame(Choreographer.java:832)
E/AndroidRuntime(10555):        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
E/AndroidRuntime(10555):        at android.os.Handler.handleCallback(Handler.java:942)
E/AndroidRuntime(10555):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(10555):        at android.os.Looper.loopOnce(Looper.java:201)
E/AndroidRuntime(10555):        at android.os.Looper.loop(Looper.java:288)
E/AndroidRuntime(10555):        at android.app.ActivityThread.main(ActivityThread.java:7872)
E/AndroidRuntime(10555):        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(10555):        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime(10555):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
D/TrafficStats(10555): tagSocket(123) with statsTag=0xffffffff, statsUid=-1
I/Process (10555): Sending signal. PID: 10555 SIG: 9
Lost connection to device.

当使用旧版 ArcGIS Runtime SDK for Android v100.15.2 时,它将按预期工作:

// android/app/src/main/kotlin/com/example/test/NativeView.kt
package com.example.test

import android.content.Context
import android.view.View

import io.flutter.plugin.platform.PlatformView

import com.esri.arcgisruntime.ArcGISRuntimeEnvironment
import com.esri.arcgisruntime.mapping.ArcGISMap
import com.esri.arcgisruntime.mapping.view.MapView
import com.esri.arcgisruntime.mapping.BasemapStyle
import com.esri.arcgisruntime.mapping.Viewpoint

internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?) : PlatformView {
    private val mapView: MapView

    init {
        ArcGISRuntimeEnvironment.setApiKey("<hidden>")

        mapView = MapView(context)
        mapView.map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC)
        mapView.setViewpoint(Viewpoint(34.0270, -118.8050, 72000.0))
    }

    override fun getView(): View {
        return mapView
    }

    override fun dispose() {}
}

启动后,我可以看到正在显示的地图视图:

我不是一名经验丰富的 Android 开发人员。有谁知道 v200.1 方法有什么问题吗?

版本信息:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.6, on macOS 13.4.1 22F770820d darwin-x64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] VS Code (version 1.80.1)
[✓] VS Code (version 1.81.0-insider)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!

编辑:有人尝试使用 React Native 做完全相同的事情,并在启动时得到相同的运行时异常(StackOverflow post)。然而不幸的是,没有人回复该帖子。

android flutter kotlin arcgis arcgis-runtime
1个回答
0
投票

Arcgis SDK 版本 200.15.2 要求您的 Activity 扩展 AppCompatActivity() 并让生命周期观察您的地图视图

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycle.addObserver(mapView) // <= you need this
    }

我在使用Arcgis和Platformview时遇到了和你同样的问题,并提出了两种方法:

  1. 同时扩展了
    PlatformView
    AppCompatActivity()
    -> 我还没有测试过这个方法
internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?) : PlatformView, AppCompatActivity() {
    private val mapView: MapView

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)

  lifecycle.addObserver(mapView) // <= you need this
}
  1. 不使用 Platformview,而是创建一个扩展
    AppCompatActivity()
    的 Activity 并使用 Flutter 中的 invokeMethodChannel 来打开该 Activity -> 这对我有用
© www.soinside.com 2019 - 2024. All rights reserved.