attachAndroidMap method

  1. @override
Future<void> attachAndroidMap(
  1. int viewId
)
override

Implementation

@override
Future<void> attachAndroidMap(int viewId) async {
  if (_disposeFuture != null) {
    throw AndroidMapException(
      operation: 'attach',
      code: 'controller_disposed',
      viewId: viewId,
    );
  }
  if (_attachStarted || _attaching || _viewId != null) {
    throw AndroidMapException(
      operation: 'attach',
      code: 'already_attached',
      viewId: _viewId ?? viewId,
    );
  }

  _attachStarted = true;
  _attaching = true;
  try {
    final candidates = backend == AndroidMapBackend.auto
        ? const [AndroidMapBackend.jni, AndroidMapBackend.methodChannel]
        : [backend];

    for (final candidateBackend in candidates) {
      AndroidMapTransport? candidate;
      try {
        candidate = _transportFactory(candidateBackend);
        await candidate.attach(viewId);
        if (_disposeFuture != null) {
          throw AndroidMapException(
            operation: 'attach',
            code: 'controller_disposed',
            viewId: viewId,
          );
        }
      } catch (error, stackTrace) {
        await candidate?.close();
        final exception = _asException(
          error,
          operation: 'attach',
          viewId: viewId,
        );
        final mayFallback =
            _disposeFuture == null &&
            backend == AndroidMapBackend.auto &&
            candidateBackend == AndroidMapBackend.jni;
        if (mayFallback) {
          continue;
        }
        _completeReadyError(exception, stackTrace);
        throw exception;
      }

      _transport = candidate;
      _viewId = viewId;
      _transportEvents = candidate.events.listen(
        _onTransportEvent,
        onError: _onTransportError,
      );

      try {
        await candidate.initialize(initialPosition: initPosition!);
        return;
      } catch (error, stackTrace) {
        // Initialization is the first state-changing command. Never replay
        // it through another backend after it has been attempted.
        final exception = _asException(
          error,
          operation: 'initialize',
          viewId: viewId,
        );
        await _releaseTransport();
        _completeReadyError(exception, stackTrace);
        throw exception;
      }
    }

    final exception = AndroidMapException(
      operation: 'attach',
      code: 'no_backend_available',
      viewId: viewId,
    );
    _completeReadyError(exception, StackTrace.current);
    throw exception;
  } finally {
    _attaching = false;
  }
}