2020-05-09に更新

Flutterのネイティブで重い処理をさせる方法(Android)

Flutterを使ってAndroidのネイティブで重い処理をさせているとおかしくなることがあった。具体的にはFutureBuilderを使っている時に気づいたのだが、いつまでたってもFutureBuilderが完了状態にならない。

そういえば以前から下記のようなログが出ていることを思い出した。

Skipped 229 frames! The application may be doing too much work on its main thread

これはメインスレッドでの処理が重すぎるから途中でやめちゃったよ、というAndroid側のメッセージ。ということで、この処理を別スレッドで実行してあげる必要がある。例えば元々下記のような処理を行っているとする。

if (call.method == "heavy") {
    myInstance.heavyAction()
    result.success(true)
}

上記を別スレッドにする必要がある。あまりここに色々詰め込みたくなかったのでメソッド内に記述した。

fun heavyAction(callback: () -> Unit) {
    thread {
        heavy()
        callback()
    }
}

呼び出し側

if (call.method == "heavy") {
    myInstance.heavyAction() {
        result.success(true)
    }
}

これで良さそうに思うのだが、今度は下記のエラーが出る。

Methods marked with @UiThread must be executed on the main thread

完了処理を別スレッドで行わず、メインUIスレッドで行なえ、とのこと。

ということで最終的に呼び出し元は下記のようになった。

if (call.method == "heavy") {
    myInstance.heavyAction() {
        runOnUiThread {
            result.success(true)
        }
    }
}
ツイッターでシェア
みんなに共有、忘れないようにメモ

だら@Crieit開発者

Crieitの開発者です。 Webエンジニアです(在宅)。大体10年ちょい。 記事でわかりにくいところがあればDMで質問していただくか、案件発注してください。 業務依頼、同業種の方からのコンタクトなどお気軽にご連絡ください。 業務経験有:PHP, MySQL, Laravel, Vue.js, React, Node, RoR 趣味:Elixir, Phoenix, Nuxt, Express, GCP, AWS等色々

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!
ボードとは?

関連記事

コメント