質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.00%

Xamarin Android で大量の画面遷移をしたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 166

oshibori

score 1

前提・実現したいこと

会話形式でデータを入力するアプリを開発中です。
このため、非常にたくさんの画面遷移が必要になります。
1回のサイクルは、画面1~画面5で、画面の最後にデータを登録するというものです
これは、ユーザーが終了するまで永遠に続きます
しかし、実際に実行させてみると Activity に含まれるデータ量に関わらず、750回画面切り替えるとフリーズ後に落ちてしまいます。
どのようにすれば、延々とデータ入力を繰り返すことができるのでしょうか?

発生している問題・エラーメッセージ

エラーメッセージは特に表示されません。

該当のソースコード

public class Gamen1Activity : Activity
{
    private Button _button;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);
        _button = FindViewById<Button>(Resource.Id.SystemStartButton);
        _button.Text = "Button";
        _button.Click += (s, e) => {
            var nextType = typeof(Gamen2Activity); // ここで次の Activity を指定する
            var nextIntent = new Intent(this, nextType)
            StartActivity(nextIntent);
        };
    }
}

試したこと

StartActivity で画面遷移後に、呼び出した Activity にて Finish メソッドを実行しました。

補足情報(FW/ツールのバージョンなど)

実行中に、出力ウィンドウにてメモリの増加を確認しましたが、Finish にて完全に開放されていないようでした。
Xamarin や Andoroid の開発は初めてで、ネットの情報を調べながら、上記要件の処理に対して、どのような方法が良いのかについて調べましたが、明確な情報を得ることができませんでした。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • coco_bauer

    2019/11/20 17:37

    var nextIntent = new Intent(this, nextType) で新しいIntentを作ってますよね。質問のコードには、使い終わったIntentを削除する部分が無いので、どんどんメモリがIntentで埋まっていって、埋め尽くされたところでフリーズが起きているのではと想像します。使わなくなったIntentを開放するようにすれば、改善するのでは?

    キャンセル

  • oshibori

    2019/11/23 14:09

    ありがとうございます。
    nextIntent を解放するとは、Activity を Finish する直前に、Intent.Dispose() するということでしょうか?

    キャンセル

回答 1

checkベストアンサー

+1

どのようなアプリは分からなものの、「750回超もの(永遠に、延々と)画面遷移に耐えられる事」は過剰要件な気がしますが、解決必須ということであればご参考になれば。

ひとつは、問題を単純化するために Xamarin.Android の使用をやめ、Android Studio(Java または Kotlin)で同様の再現を試みることです。

Xamarin.Android は、Java の世界のメモリ管理に加え、.NET の世界のメモリ管理も並行して行っているため、どちらで問題が起こっているか切り分けが難しいです。

次に、Android Studio(Java または Kotlin)で問題の再現ができれば、どこでメモリリークが発生しているかを突き止められます。これには LeakCanary というライブラリが便利です。

同種のライブラリは他にもあるかも知れません。

また、基本的なところですが、

Finish にて完全に開放されていないようでした

Activity のメモリ管理は Android OS に委ねられているので、Finish したらすぐにメモリが開放されることは通常ありません。
また、Java(JVM) でもあるのでガベージコレクトが実行されなければメモリが開放されることはありません。ガベージコレクトは java.lang.System.gc() で強制的に実施できます。

なので上記コードで言えば _button のようなクラス内変数のインスタンスは、Activity がシステムにより破棄され、ガベージコレクトが実施されない限り残ることになります。

それでも通常は、システムが「メモリが少なくなってきた」ことを検知して適宜 Activity を破棄してくれるはずなのでそれほど気にしないです。

尚、開発者向け設定で「アクティビティを保持しない」と ON にすると、より積極的に Activity が破棄されると思います。

最後にこれは主観ですが、モバイル向けOSは、「永遠に動作し続ける事」よりも「突如端末が終了しても続きから復帰できる事」に重きが置かれていると考えるので、端末によっては(あるいは元の Android OS 自体にも)長時間動作に係る不具合はあってもおかしくないのでは、と思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/23 14:15

    ご回答をありがとうございました。
    試しに、ガベージコレクトの実行を明示的に書いたところ、750回から、5000回の画面遷移にも問題なく動作するようになりました。
    また、ご提示いただいたリンク先についても、ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る