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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

2回答

6498閲覧

[Android]Activity.finish()時にWindowLeakedエラーが発生してしまう。

monagano

総合スコア246

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

1グッド

1クリップ

投稿2016/12/13 06:34

編集2022/01/12 10:55

###前提・実現したいこと
Android Studio 2.2.3
compileSdkVersion 23
buildToolsVersion "24.0.1"
com.android.support:appcompat-v7:23.4.0
com.android.support:design:23.4.0

Toolbarを用いて画面遷移を行いたいのですが、
Toolbarのmenuitemを選択し、サブ画面からメイン画面へfinish()で戻る際、
画面遷移は成功するのですが、WindowLeakedエラーが発生してしまいます。

メニューが閉じる前にfinishが実行されているのが原因ではないかと考えておりますが、
対策方法がわからずにおります。

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

E/WindowManager: android.view.WindowLeaked: Activity teratail.sample.sampleapp.SubActivity has leaked window android.widget.PopupWindow$PopupDecorView{8a7553b V.E...... ......ID 0,0-588,288} that was originally added here at android.view.ViewRootImpl.<init>(ViewRootImpl.java:372) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:86) at android.widget.PopupWindow.invokePopup(PopupWindow.java:1299) at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1136) at android.support.v7.widget.AppCompatPopupWindow.showAsDropDown(AppCompatPopupWindow.java:78) at android.support.v4.widget.PopupWindowCompatKitKat.showAsDropDown(PopupWindowCompatKitKat.java:30) at android.support.v4.widget.PopupWindowCompat$KitKatPopupWindowImpl.showAsDropDown(PopupWindowCompat.java:92) at android.support.v4.widget.PopupWindowCompat.showAsDropDown(PopupWindowCompat.java:171) at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:680) at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:163) at android.support.v7.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:129) at android.support.v7.widget.ActionMenuPresenter.onSubMenuSelected(ActionMenuPresenter.java:298) at android.support.v7.view.menu.MenuBuilder.dispatchSubMenuSelected(MenuBuilder.java:306) at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:976) at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:948) at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:618) at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:139) at android.view.View.performClick(View.java:5273) at android.view.View$PerformClick.run(View.java:21225) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:5526) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

###該当のソースコード

  • MainActivity.java

java

1package teratail.sample.sampleapp; 2 3import android.content.Intent; 4import android.os.Bundle; 5import android.support.design.widget.FloatingActionButton; 6import android.support.design.widget.Snackbar; 7import android.support.v7.app.AppCompatActivity; 8import android.support.v7.widget.Toolbar; 9import android.view.View; 10import android.view.Menu; 11import android.view.MenuItem; 12 13public class MainActivity extends AppCompatActivity { 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_main); 19 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 20 setSupportActionBar(toolbar); 21 } 22 23 @Override 24 public boolean onCreateOptionsMenu(Menu menu) { 25 getMenuInflater().inflate(R.menu.menu_main, menu); 26 return true; 27 } 28 29 @Override 30 public boolean onOptionsItemSelected(MenuItem item) { 31 switch(item.getItemId()) { 32 case R.id.action_main: 33 break; 34 case R.id.action_sub: 35 startActivity(new Intent(this,SubActivity.class)); 36 break; 37 default: 38 break; 39 } 40 return super.onOptionsItemSelected(item); 41 } 42} 43
  • SubActivity.java

java

1package teratail.sample.sampleapp; 2 3import android.content.Intent; 4import android.os.Bundle; 5import android.support.design.widget.FloatingActionButton; 6import android.support.design.widget.Snackbar; 7import android.support.v7.app.AppCompatActivity; 8import android.support.v7.widget.Toolbar; 9import android.view.Menu; 10import android.view.MenuItem; 11import android.view.View; 12 13public class SubActivity extends AppCompatActivity { 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_sub); 19 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 20 setSupportActionBar(toolbar); 21 } 22 @Override 23 public boolean onCreateOptionsMenu(Menu menu) { 24 getMenuInflater().inflate(R.menu.menu_main, menu); 25 return true; 26 } 27 28 @Override 29 public boolean onOptionsItemSelected(MenuItem item) { 30 switch(item.getItemId()) { 31 case R.id.action_main: 32 finish();//←ここでエラー発生 33 break; 34 case R.id.action_sub: 35 break; 36 default: 37 break; 38 } 39 return super.onOptionsItemSelected(item); 40 } 41} 42
  • menu_main.xml

Toolbar上のメニュー表示を三点リーダ(…)ではなく、「Menu」という文字列にするために、
menu>item>menuとネストしています
menu_mainの書き方がそもそも間違っているかも??

xml

1<menu xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto"> 3 <item 4 android:id="@+id/overflow_options" 5 android:title="Menu" 6 app:showAsAction="always"> 7 <menu> 8 <item 9 android:id="@+id/action_main" 10 android:orderInCategory="100" 11 android:title="MainActivity" 12 app:showAsAction="always" /> 13 <item 14 android:id="@+id/action_sub" 15 android:orderInCategory="100" 16 android:title="SubActivity" 17 app:showAsAction="always" /> 18 </menu> 19 </item> 20</menu>

以下、ソースコード全文
https://github.com/Monagano/sampleApp_teratailQ1

###試したこと
finishを遅延実行させたところ、エラーが発生しなかったため、
応急処置として以下のコードを採用しています。

Java

1case R.id.action_main: 2 //finish();//ここだとエラー 3 new Handler().postDelayed(new Runnable() { 4 @Override 5 public void run() { 6 finish();//ここなら正常 7 } 8 },300);//300msは適当な値(100msだと早すぎてエラーとなりました)

finish処理時点でサブメニューの描画処理が終わっていないのが問題だと思うのですが、
サブメニューを明示的に閉じ、完了を待つすべがわかりません。
finish()手前でtoolbar.dismissPopupMenus()を行ってみましたが、改善しませんでした。

android初学者なため、的外れな質問となっていないか不安です。
よろしくお願いいたします。

KiyoshiMotoki👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ポップアップを閉じずにfinish()を呼ぶとリークするようです。
http://www.programering.com/a/MTOzkzNwATE.html

java

1closeOptionsMenu(); 2finish();

とやってみてはどうでしょうか

投稿2016/12/18 12:31

choonesu

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

monagano

2016/12/19 03:04

回答いただきありがとうございます。 finish前にcloseOptionsMenu()を追記してみましたが、残念ながら現象は解決しませんでした。 1点判明したのが、テスト用端末のxperia z5のデバッグ時に発生していたのですが、 本番用端末のAllowsM03で実行したところ、同一コードでもエラーが発生しなくなりました。 端末依存で発生する問題かもしれません...
guest

0

試しにActivity#runOnUiThread内のRunnableでfinishを実行してみてください。

投稿2016/12/13 06:58

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

monagano

2016/12/13 09:24

回答いただきありがとうございます。 以下の通り実装してみました。 実装方法に問題があるのか、同じエラーが出力されてしまいました。 case R.id.action_main: //finish(); runOnUiThread(new Runnable() { @Override public void run() { finish();//ここでエラー } }); また、以下のようにディレイ(300ms)を追加してみたところ、エラーが出力されずに動作しましたが、 根本的な原因が理解できず、この方法を採用してよいのか判断に窮しています。 case R.id.action_main: //finish(); new Handler().postDelayed(new Runnable() { @Override public void run() { finish(); } },300);
yona

2016/12/13 09:40

runOnUiThreadを使う方法は処理順が怪しいのでダメでした。ごめんなさい。 方法としてはあっていると思います。 下記の2つが怪しいです。 ・ポップアップを閉じずにアクティビティを終了しようとしている。 ・アクティビティを終了しているのにsuper.onOptionsItemSelected(item)を呼んでいる。 そこで、試しにHandlerの解決策を使わずに、finishするときはbreakせずにreturn trueを呼んでみてください。
monagano

2016/12/13 09:56

回答いただきありがとうございます。 以下の通り実装してみました。 デバッグ実行したところ、何故か、return super~に遷移してしまい、 return trueに遷移しませんでした。 ■ブレークポイントには以下の警告が表示されていました。 Line 39 in SubActivity.onOptionsItemSelected() (teratail.sample.sampleapp)   No executable code found at line 39 in class teratail.sample.sampleapp.SubActivity Suspend: thread ※エラー内容も変わらずです。 ■実装コード @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.action_main: finish();//ここでエラー return true; case R.id.action_sub: break; default: break; } return super.onOptionsItemSelected(item); }
yona

2016/12/13 10:39

通常の実行をしても同じですか?
monagano

2016/12/14 01:31

お返事が遅くなり申し訳ありません。 度々お付き合いいただきありがとうございます。 リリースモードで実行しても発生します。
yona

2016/12/14 02:19

実行プログラムとデバッグプログラムの同期が取れていないようです。 プロジェクトをクリーンし、インスタントランをせずに実行してください。
monagano

2016/12/14 06:39

Clean Project -> Rebuild Project -> Runを何度か試してみましたが、 変わらずエラーが発生します。 また、gradleのminifyをオフにして、Clean -> Debugで以下のコード実行してみましたが、 finish後に何故かelse節のsuper.on~に遷移しました。 if(item.getItemId() == R.id.action_main){ finish(); return true;//ここに遷移せず }else{ return super.onOptionsItemSelected(item);//ここに遷移してしまう }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問