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

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

ただいまの
回答率

88.22%

NullPointerExceptionがメニューボタンを押してアプリから離れた後戻るときに発生します

解決済

回答 1

投稿 編集

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

ko20vonobird

score 50

前提

SurfaceViewを使ってアプリを作っているのですが、一旦androidの端末の右下にあるメニューボタンを押してアプリ一覧に遷移した後再びアプリに戻ろうとすると下記のエラーが出ます。これは半ばソースにも記していますがufoという画像の要素に対してgetWidth()で幅を求めているものです。そこでエラーが出ました。booleanやthreadがnullではないかということを用いてnullの時はそもそも呼び出しがないようにしているつもりなのですがこのようなエラーが出てしまいます。
どのような対策があるのか教えてください、よろしくお願いします。
*新たにエラーが出ました(会話参照)

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

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
                                                                                        at jpdb.shoichi_vono_kono.airchainsaw.C.run(C.java:155)
                                                                                        at java.lang.Thread.run(Thread.java:818)

該当のソースコード

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        isSurfaceStanby = true;
        thread = new Thread(this);
        thread.start();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isSurfaceStanby = false;
        thread = null;
        if (ufo != null) {
            ufo.recycle();
            ufo = null;
        }
        if (starmae != null) {
            starmae.recycle();
            starmae = null;
        }
        if (starushiro != null) {
            starushiro.recycle();
            starushiro = null;
        }
    }
@Override
    public void run() {
        Canvas c;
        while (thread != null) {
            if (!isSurfaceStanby) return;
            c = holder.lockCanvas();
            if (c == null) return;
            c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//ここでも同じエラーが出ます
            if (linebool) {
                lineh += winH / 20;
                if (lineh >= winH) {
                    linebool = false;
                }
            }else{
                lineh -= winH / 20;
                if (lineh <= 0) {
                    linebool = true;
                }
            }
            winW = getWidth();
            winH = getHeight();
            if (!isSurfaceStanby) return;
            if (c == null) return;
            ufow = ufo.getWidth();//エラーの箇所です
            ufoh = ufo.getHeight();
//省略
            holder.unlockCanvasAndPost(c);
            try {
                Thread.sleep(50);
            }catch (Exception e) {

            }
        }
    }


修正記述↓
//ここから//ここまで、の部分が追記です。

@Override
    public void surfaceCreated(SurfaceHolder holder) {
//ここから
        res = this.getContext().getResources();
        ufo = BitmapFactory.decodeResource(res, R.drawable.ufocomp);
        starmae = BitmapFactory.decodeResource(res, R.drawable.starskymae);
        starushiro = BitmapFactory.decodeResource(res, R.drawable.starskyushiro);
//ここまで
        isSurfaceStanby = true;
        thread = new Thread(this);
        thread.start();
    }



エラー

java.lang.OutOfMemoryError
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

ufoはどのように初期化されているのでしょうか?
一度、SurfaceViewが破棄されるとufoはnullになります、その後SurfaceViewを使用する時にufoを初期化する処理は行われていますか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/13 23:05

    考えられないですね。
    この変更と同時に他の個所でコードを書き換えたりはしていませんか?

    質問当初のコードでの初期化処理と新しく追加した4文は同じ処理ですか?

    キャンセル

  • 2017/06/13 23:44 編集

    この変更以外に他の箇所でコードを書き換えたりはしていません。

    はい、全く同じの以下四文を処理させています。
    res = this.getContext().getResources();
    ufo = BitmapFactory.decodeResource(res, R.drawable.ufocomp);
    starmae = BitmapFactory.decodeResource(res, R.drawable.starskymae);
    starushiro = BitmapFactory.decodeResource(res, R.drawable.starskyushiro);

    キャンセル

  • 2017/06/14 13:09

    エラーを回避できるかと思いsurfaceCreatedにif(ufo != null && starmae != null && starushiro != null){}で画像.recycle();画像 = null;とする記述を四文の前に書いたところエラーで止まることが数回やってなくなることが確認できました。なぜこれだけしかない容量でこのエラーが出るのかは依然としてわかりませんが、とりあえず表題は解決できたので解決とさせて頂こうかと思います。また同じようなエラーが出た場合は別の質問枠にて質問させて頂こうとおもいます。ありがとうございました。

    キャンセル

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

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

関連した質問

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