はじめに
Tauriとは
Tauriとは、デスクトップアプリ(Windows, macOS, Linux)およびモバイルアプリ(iOS, Android)1を開発することができるフレームワークです。フロントエンドはWebの技術(HTML, CSS, TypeScript)を使用し、バックエンドはRustで書くことができます。いわゆるクロスプラットフォームと呼ばれるもので、ワンソースで複数のOS向けにアプリを開発できます。
この記事は何?
Tauriで開発するAndroidアプリにおいて、戻るボタン押下イベントを検知し、フロントエンド側(TypeScript)で制御する方法を紹介します。
npm run tauri android dev
コマンドによって自動で生成された WryActivity
を見ると、WebViewの canGoBack()
, goBack()
メソッドにより戻る操作を制御していることがわかります。
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
mWebView.goBack()
return true
}
return super.onKeyDown(keyCode, event)
}
Webページのヒストリーに則った画面遷移をしているならば、このままで良さそうですが、ヒストリーを利用していないSPAなどでは、戻るボタン押下でいきなりアプリが終了するといった挙動になってしまいます。
戻るボタン押下イベントを制御するやり方は、公式サポートには無さそうなので、自前で実装します。
戻るボタン押下イベントの制御
MainActivityの修正
自動生成された src-tauri/gen/android/app/src/main/java/path/to/MainActivity.kt
に以下のコードを追記します。
+ import android.webkit.WebView
class MainActivity : TauriActivity() {
+ private var webView: WebView? = null
+ override fun onWebViewCreate(webView: WebView) {
+ this.webView = webView
+ super.onWebViewCreate(webView)
+ }
+ @Deprecated("Deprecated in Java")
+ override fun onBackPressed() {
+ webView?.run {
+ evaluateJavascript(
+ """
+ try {
+ window.onAndroidBackPressed()
+ } catch (_) {
+ true
+ }
+ """.trimIndent()
+ ) { result ->
+ if (result == "true") {
+ super.onBackPressed();
+ }
+ }
+ } ?: super.onBackPressed()
+ }
}
このコードは、戻るボタンが押されたとき、 evaluateJavascript
によって
window.onAndroidBackPressed()
を実行します。 onAndroidBackPressed
関数がtrueを返す場合はデフォルトの戻る操作を行い、falseを返す場合はデフォルトの戻る操作をキャンセルします。
フロントエンド側の修正
以下の AndroidBackPressedController.ts
ファイルを追加します。本稿では src
ディレクトリ直下に置いています。
export type OnAndroidBackPressedListener = () => boolean;
export default class AndroidBackPressedController {
private listener?: OnAndroidBackPressedListener;
constructor() {
// @ts-ignore
window.onAndroidBackPressed = () => {
// trueを返すとデフォルトの動作、falseを返すとデフォルトの動作をキャンセル
return this.listener?.() ?? true;
};
}
setListener(listener: OnAndroidBackPressedListener) {
this.listener = listener;
}
removeListener() {
this.listener = undefined;
}
}
上記の AndroidBackPressedController
クラスのインスタンスをAppコンポーネント内で生成し、リスナーを登録します。 AndroidBackPressedController
インスタンスが生成されるタイミングで onAndroidBackPressed
関数がセットされます。この関数は、戻るボタンが押された際にKotlinから evaluateJavascript
を通して実行されます。
function App() {
...
new AndroidBackPressedController().setListener(() => {
// TODO: 戻るボタンが押された時の処理
return false;
});
...
}
リスナーに登録した関数内で戻るボタンが押された時の処理を実装します。falseを戻り値として返すことで、デフォルトの戻る操作はキャンセルされます。
おわりに
今回は、Tauriで開発するAndroidアプリにおいて、戻るボタン押下イベントをフロントエンド側で制御する方法を紹介しました。SPAなどのモダンなWebアプリをTauriでAndroidアプリ化する際に、この方法が参考になれば幸いです。
-
Tauri 2.0で正式にiOS, Androidアプリが開発できるようになりました。https://v2.tauri.app/blog/tauri-20/ ↩