はじめに
FlutterでWebViewを利用するためのプラグインとしてwebview_flutterが存在する。しかし公式のサポートプラットフォームはiOSとAndroidのみとなっている。公式のWebViewプラグインと同じAPIをサポートするLinux版のWebViewを提供するプラグインが公開されたので、そのプラグインの動作を確認する。
筆者の環境の都合上M1 Macでの開発環境構築となっている。
Flutterの開発環境を用意する
Linux向けのFlutter開発環境を用意する。
M1Mac向けにUbuntu22.04を用意する
Armチップを搭載しているMacBookでLinux環境を実行する仮想環境を用意するならUTMが利用できる。いわゆるM1 MacでLinux環境を用意する場合には下記のサイトが参考になるだろう。
Flutterをインストールする
公式でサポートされている環境であればパッケージを利用してflutterをインストールするのが楽で良い。
Ubuntu22.04のsnap版のflutterは利用不可
flutter_linux_webviewを利用しようとするとライブラリの依存関係の問題でリンクに失敗してしまう。Ubuntu22.04を利用している場合にはflutterはマニュアルでインストールして利用する。
最新情報は公式サイトを参照すること
Flutterをマニュアルインストール
Linux用SDKパッケージのアーカイブがFlutterの公式サイトで配布されている。残念ながらLinux版はx86版のアーカイブしか公開されていないため、Arm64版のLinux向けのFlutterはGitHubからインストールする。
$ cd
$ git clone git@github.com:flutter/flutter.git
$ export PATH="$PATH:$HOME/flutter/bin"
$ which flutter dart
/home/raiko/flutter/bin/flutter
/home/raiko/flutter/bin/dart
$ flutter --version
Flutter 3.20.0-1.0.pre.18 \u2022 channel master \u2022 https://github.com/flutter/flutter
Framework \u2022 revision da375a7796 (6 hours ago) \u2022 2024-02-04 00:09:20 -0500
Engine \u2022 revision f34c658b96
Tools \u2022 Dart 3.4.0 (build 3.4.0-99.0.dev) \u2022 DevTools 2.31.0
flutter doctor コマンドでFlutterの環境の確認する。
Android(スマホ用)とChrome(Web用)の環境がないが、Linux環境はインストールされている。AndroidやWeb向け開発環境は今回は必要ないので無視して進める。
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[\u2713] Flutter (Channel master, 3.20.0-1.0.pre.18, on Ubuntu 22.04.3 LTS 5.15.0-92-generic, locale en_US.UTF-8)
[\u2717] Android toolchain - develop for Android devices
\u2717 Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[\u2717] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[\u2713] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[\u2713] VS Code (version 1.86.0)
[\u2713] Connected device (1 available)
[\u2713] Network resources
! Doctor found issues in 3 categories.
Linuxのデスクトップアプリを開発する環境を整える
FlutterでLinux向けデスクトップアプリケーションを作成するために必要になるツールとライブラリ一式をインストールする。
$ sudo apt-get update
$ sudo apt-get install clang cmake git ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev
$ flutter config --enable-linux-desktop
Flutterの開発環境を確認する
FlutterのSDKのインストールが終了した後は開発環境を整える。Flutterは数多くの機能をサポートしており、1つ1つ手作業で進めるのはなかなかに面倒である。公式でサポートされている Visual Source Code の Flutter拡張機能を利用する。
エディタの設定
Visual Source Code(vscode)での開発が便利なのでそれを利用することがおすすめだ。
公式の設定方法に従ってインストールを進める。
vscodeがインストールできたら、flutterの拡張をインストールを忘れないように実施する。
サンプルアプリを実行する
公式ガイドにしたがってサンプルアプリを作成して実行してみる。
WebViewアプリを作成する
サンプルアプリを作成して実行できるようになったら、そのサンプルアプリにWebViewを組み込んでみよう。
サンプルアプリを用意
先ほど作成したサンプルアプリと全く同じサンプルアプリをwebviewというプロジェクト名で用意する。
WebViewプラグインをインストールする
flutter_linux_webviewの公式サイトの説明にしたがってサンプルアプリを改変する。
プラグインのインストール
$ flutter pub add flutter_linux_webview:'^0.1.0'
$ flutter pub add webview_flutter:'^3.0.4'
CMakeLists.txt の修正
linux/CMakeLists.txt
のadd_executable(${BINARY_NAME})
より後ろの行に下記を追加
include(flutter/ephemeral/.plugin_symlinks/flutter_linux_webview/linux/cmake/link_to_cef_library.cmake)
main.dart を置き換え
lib/main.dart
を公式ページのサンプルプログラムで置き換える
import 'dart:async';
// Required to use AppExitResponse for Fluter 3.10 or later
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter_linux_webview/flutter_linux_webview.dart';
void main() {
// ensureInitialized() is required if the plugin is initialized before runApp()
WidgetsFlutterBinding.ensureInitialized();
// Run `LinuxWebViewPlugin.initialize()` first before creating a WebView.
LinuxWebViewPlugin.initialize(options: <String, String?>{
'user-agent': 'UA String',
'remote-debugging-port': '8888',
'autoplay-policy': 'no-user-gesture-required',
});
// Configure [WebView] to use the [LinuxWebView].
WebView.platform = LinuxWebView();
runApp(const MaterialApp(home: _WebViewExample()));
}
class _WebViewExample extends StatefulWidget {
const _WebViewExample({Key? key}) : super(key: key);
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<_WebViewExample>
with WidgetsBindingObserver {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
/// Prior to Flutter 3.10, comment out the following code since
/// [WidgetsBindingObserver.didRequestAppExit] does not exist.
// ===== begin: For Flutter 3.10 or later =====
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Future<AppExitResponse> didRequestAppExit() async {
await LinuxWebViewPlugin.terminate();
return AppExitResponse.exit;
}
// ===== end: For Flutter 3.10 or later =====
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('flutter_linux_webview example'),
),
body: WebView(
initialUrl: 'https://flutter.dev',
initialCookies: const [
WebViewCookie(name: 'mycookie', value: 'foo', domain: 'flutter.dev')
],
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptMode: JavascriptMode.unrestricted,
),
floatingActionButton: favoriteButton(),
);
}
Widget favoriteButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String useragent = (await controller.data!
.runJavascriptReturningResult('navigator.userAgent'));
final String title = (await controller.data!.getTitle())!;
final String url = (await controller.data!.currentUrl())!;
final String cookies = await (controller.data!
.runJavascriptReturningResult('document.cookie'));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'userAgent: $useragent, title: $title, url: $url, cookie: $cookies'),
),
);
},
child: const Icon(Icons.favorite),
);
}
return Container();
});
}
}
WebViewアプリの実行
作成したWebViewアプリを実行する。
$ flutter run
YouTubeを表示する
initialUrl
をhttps://www.youtube.com
に変更すればyoutubeをブラウジングすることも可能だ。もちろん音声再生もサポートされている。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('flutter_linux_webview example'),
),
body: WebView(
initialUrl: 'https://www.youtube.com',
initialCookies: const [
WebViewCookie(name: 'mycookie', value: 'foo', domain: 'flutter.dev')
],