launch method

Future<void> launch(
  1. Function? onLaunched, {
  2. String? jsCode,
  3. Function? socketDisconnectedAction,
})

Implementation

Future<void> launch(
  Function? onLaunched, {
  String? jsCode,
  Function? socketDisconnectedAction,
}) async {
  /// reset state before webView launch or reload
  _msgHandlers = {};
  _msgCompleters = {};
  _msgJavascript = {};
  _reloadHandlers = {};
  _evalJavascriptUID = 0;
  if (onLaunched != null) {
    _onLaunched = onLaunched;
  }
  webViewLoaded = false;
  _webViewOOMReload = false;
  jsCodeStarted = -1;

  _jsCode = jsCode;

  if (_web == null) {
    await LocalServer.getInstance().startLocalServer();
    _web = new HeadlessInAppWebView(
      initialOptions: InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(clearCache: true),
        android: AndroidInAppWebViewOptions(useOnRenderProcessGone: true),
      ),
      androidOnRenderProcessGone: (webView, detail) async {
        if (_web?.webViewController == webView) {
          webViewLoaded = false;
          _webViewOOMReload = true;
          await _web?.webViewController.clearCache();
          await _web?.webViewController.reload();
        }
      },
      initialUrlRequest: URLRequest(
          url: Uri.parse(
              "http://localhost:8080/packages/polkawallet_sdk/assets/index.html")),
      onWebViewCreated: (controller) {
        print('HeadlessInAppWebView created!');
      },
      onConsoleMessage: (controller, message) {
        print("CONSOLE MESSAGE: " + message.message);
        if (jsCodeStarted < 0) {
          try {
            final msg = jsonDecode(message.message);
            if (msg['path'] == 'log') {
              if (message.message.contains('js loaded')) {
                jsCodeStarted = 1;
              } else {
                jsCodeStarted = 0;
              }
            }
          } catch (err) {
            // ignore
          }
        }
        if (message.message.contains("WebSocket is not connected") &&
            socketDisconnectedAction != null) {
          socketDisconnectedAction();
        }
        if (message.messageLevel != ConsoleMessageLevel.LOG) return;

        try {
          var msg = jsonDecode(message.message);

          final String path = msg['path']!;
          final error = msg['error'];

          if (error != null) {
            if (_msgCompleters[path] != null) {
              Completer handler = _msgCompleters[path]!;
              handler.completeError(error);
              if (path.contains('uid=')) {
                _msgCompleters.remove(path);
              }
            }
          }

          if (_msgCompleters[path] != null) {
            Completer handler = _msgCompleters[path]!;
            handler.complete(msg['data']);

            _setMessageChannelAlive();

            if (path.contains('uid=')) {
              _msgCompleters.remove(path);
            }
          }
          if (_msgHandlers[path] != null) {
            Function handler = _msgHandlers[path]!;
            handler(msg['data']);

            _setMessageChannelAlive();
          }

          if (_msgJavascript[path] != null) {
            _msgJavascript.remove(path);
          }
        } catch (err) {
          // ignore
          print('msg parsing error $err');
        }
      },
      onLoadStop: (controller, url) async {
        print('webview loaded $url');
        final jsLoaded = await _web!.webViewController
            .evaluateJavascript(source: '!!account;');
        if (webViewLoaded) return;

        if (jsLoaded == true) {
          webViewLoaded = true;
          await _startJSCode();
        }
      },
      onLoadError: (controller, url, code, message) {
        print("webview restart");
        _web = null;
        launch(null,
            jsCode: jsCode,
            socketDisconnectedAction: socketDisconnectedAction);
      },
    );

    await _web?.dispose();
    await _web?.run();
  } else {
    _tryReload();
  }
}