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

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

ただいまの
回答率

89.72%

alertdialog内に設置したsurfaceviewの閉じ方について

受付中

回答 0

投稿

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

yuko0807

score 4

前提・実現したいこと

ダイアログ内に設置したsurfaceviewで描画処理を行うコードを書いております。
ダイアログは枠外をタップすることで閉じるようにしており、
アクティビティレイアウトに設置したボタンを押すことで再度ダイアログを表示できるようにしてあります。

しかしダイアログを開く、閉じるを繰り返すうちに表示が重くなります。
そこでandroidProfilerでメモリをしらべたところ、生成したsurfaceviewのインスタンスが積み重なっていることに気づいたのですが
①なぜインスタンスがGCされずに積もるのか
②解消するにはどうすべきか
を教えていただきたいと思っております。

簡易レイアウト

イメージ説明

該当のソースコード

public class BaseActivity extends AppCompatActivity {
    private DialogFragment dialogFragment;
    private FragmentManager flagmentManager;
    static DetailSurfaceView DetailSurfaceView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
    }
    public static class AlertDialogFlagment extends DialogFragment{
        private AlertDialog dialog1;
        private AlertDialog.Builder builder;
        SurfaceView sv;
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState){
            builder =new AlertDialog.Builder(getActivity());
            View alertView =getActivity().getLayoutInflater().inflate(R.layout.detail,null);
            builder.setView(alertView);
            dialog1 =builder.create();
            this.setCancelable(true);
            dialog1.show();
            return dialog1;

        }
        @Override
        public void onStart(){
            super.onStart();

            sv=dialog1.findViewById(R.id.surface);
            detailSurfaceView= new DetailSurfaceView(getContext(),sv);
        }
        @Override
        public void onStop(){
            super.onStop();
            detailSurfaceView=null;
            sv=null;
        }

    }
    //ボタンID:showButtonからの呼び出し
    public void showDialog(View view){
        flagmentManager = getSupportFragmentManager();
        dialogFragment = new AlertDialogFlagment();
        dialogFragment.show(flagmentManager,"test");
    }
}
public class DetailSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    static SurfaceHolder surfaceHolder;
    Thread thread;
    static int screen_width;
    static int screen_height;
    static long t;
    public static final int FLAME =20;
    public DetailSurfaceView(Context context,SurfaceView sv){
        super(context);
        surfaceHolder =sv.getHolder();
        surfaceHolder.addCallback(this);
        paint = new Paint();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder){
        if(thread == null){
            thread= new Thread(DetailSurfaceView.this);
        }
        thread.start();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){
        screen_width=width;
        screen_height=height;
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        thread.interrupt();
    }
    @Override
    public void run(){
        t=0;
        while(!thread.isInterrupted()){
            final long startTime = System.currentTimeMillis();
            final SurfaceHolder holder = surfaceHolderresult;
            final Canvas canvas =holder.lockCanvas();
            if(canvas!=null){
                try{
                    t++;

                    //描画処理

                }finally {
                    holder.unlockCanvasAndPost(canvas);
                }
            }
            final long elapsed =System.currentTimeMillis() - startTime;
            final long wait = FLAME - elapsed;
            if(0 < wait){
                try{
                    Thread.sleep(wait);
                }catch (final InterruptedException e){
                    break;
                }
            }
        }
        thread=null;
    }
}

試したこと

onStop()を上書きしてdetailsurfaceview=null を実施しましたが、ダイアログを開いた数だけインスタンスが
残っているようです。(インスタンスが25あるということ以外、この画面の調べ方・使い方は存じ上げておりません。)
イメージ説明

補足情報

実際のコードは変数名も読み手の方にとって煩わしい部分もございましたので質問用に変更しております。
私が現在心得ている(つもりになっている)のは、
・参照が切れないとGCされない
・インスタンスはnullを代入すると参照が切れる
の2点です。
ダイアログを開く回数を重ねるごとに重くなるのは、GCされていないことにあるのだと考えておりますが、
ダイアログを閉じる(キャンセルする)ごとに、中に設置しているsurfaceviewもきれいさっぱり無くすことが解決かと思っております。
そこで、これらdialogと、surfaceviewのコードの書き方に原因が見いだせずにおりますので、ご教授お願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

まだ回答がついていません

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

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