次のコードをご覧ください。
問題
「ホームボタン」をクリックすると、exception
がスローされます:Activity
はウィンドウをリークしています...この行から:
_localWindowManager.addView(colourView, layoutParams);
_
質問(s)
何が原因であるか知っていますか?
[戻る]ボタンでアプリケーションを閉じても問題は発生しません。
例外/エラーログ
_W/InputManagerService( 96): Starting input on non-focused client com.Android.internal.view.IInputMethodClient$Stub$Proxy@40908148 (uid=10056 pid=1368)
D/CordovaActivity( 1368): CordovaActivity.onDestroy()
D/CordovaWebView( 1368): >>> loadUrlNow()
E/WindowManager( 1368): Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368): Android.view.WindowLeaked: Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368): at Android.view.ViewRoot.<init>(ViewRoot.Java:258)
E/WindowManager( 1368): at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:148)
E/WindowManager( 1368): at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:91)
E/WindowManager( 1368): at Android.view.Window$LocalWindowManager.addView(Window.Java:424)
E/WindowManager( 1368): at pl.edu.uj.tcs.student.xxx.Display.setColorsViews(Display.Java:181)
E/WindowManager( 1368): at pl.edu.uj.tcs.student.xxx.Display$3.run(Display.Java:139)
E/WindowManager( 1368): at Android.os.Handler.handleCallback(Handler.Java:587)
E/WindowManager( 1368): at Android.os.Handler.dispatchMessage(Handler.Java:92)
E/WindowManager( 1368): at Android.os.Looper.loop(Looper.Java:130)
E/WindowManager( 1368): at Android.app.ActivityThread.main(ActivityThread.Java:3683)
E/WindowManager( 1368): at Java.lang.reflect.Method.invokeNative(NativeMethod)
E/WindowManager( 1368): at Java.lang.reflect.Method.invoke(Method.Java:507)
E/WindowManager( 1368): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:839)
E/WindowManager( 1368): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:597)
E/WindowManager( 1368): at dalvik.system.NativeStart.main(Native Method)
D/CordovaActivity( 1368): onMessage(onPageStarted,about:blank)
D/CordovaWebViewClient( 1368): onPageFinished(about:blank)
D/CordovaActivity( 1368): onMessage(onPageFinished,about:blank)
D/CordovaActivity( 1368): onMessage(exit,null)
I/power ( 96): *** set_screen_state 0
_
編集:
CordovaアクティビティのonPause()、onStop()などの関数に何かを追加するにはどうすればよいですか?
編集2:
なぜそれが問題なのですか?私が作成するのは、CordovaPluginと小さな補助クラスを拡張するクラスだけだからです。それで全部です。 Activityクラスの本文を変更することはできません(おそらく)。私ができることは、cordova.getActivity()
関数を呼び出すことでそれへの参照を取得することだけです。
プログラミングのリークとは何ですか?
獲得して解放しないメモリはメモリリークにつながります。(windows/dialogs)でも同様のことが起こります。
ここで何が起こっていますか?
ウィンドウを追加しようとしており、ウィンドウが表示されている間にフォアグラウンドにありますが、ホームボタンを押すと一時停止してから停止します(onStop()およびonPause()にトーストを入れてみてください)。
ビューを削除するようにシステムに指示しなかったため、ウィンドウにアタッチされたままになり、ウィンドウはアプリケーションから消えた/デタッチされました。したがって、システムによると、customViewは解放されなかったスペースを占有しました。
ソリューション
onStop() or onPause()
andonDestroy()
内で、必ずビューを閉じる(dismiss()
ダイアログの場合)または削除する(remove()
window Managerを使用して追加した場合) 。
戻るボタンを押すとこのエラーが発生することを述べたように、on unload関数内にdismissまたはremove関数を追加します。アプリを終了するとonUnload()
メソッドが呼び出されます。
提案(コンテキストにない場合は無視)
私が見ることができるように、あなたはその下にあるものの上に来るシステムアラートウィンドウを作成しようとしています。アクティビティにそのような種類のポップアップを追加すると、漏れの問題を引き起こす可能性があるため危険です。実際にService
を介してこのような種類のウィンドウを追加すると、アクティビティの存続期間が長くなり、デバイス上のあらゆる場所に表示されます(必要な場合)。
2-コルドバのライフサイクルを更新
CordovaPluginクラスのonUnloadメソッドをオーバーライドしてみませんか?私は見つけようとしましたが、 docs はonPauseおよびonResumeメソッドの存在に言及しています。CordovaPluginクラスでonUnloadを取得したら、ビューを削除します。ビュークラスでrunOnUiThreadメソッドを作成しています。
アクティビティを終了した後、Dialog
を表示しようとしています。
解決策は、Dialog
を終了する前に作成したActivity
でdismiss()
を呼び出すことです。 onPause()で。 Activity
を残す前に、すべてのウィンドウとダイアログを閉じる必要があります。
@Override
protected void onStop() {
super.onStop();
if (loadingDlg != null) {
loadingDlg.dismiss();
loadingDlg = null;
}
}
お役に立てば幸いです。
ダイアログに表示されている天気を確認するかどうか
@Override
protected void onStop() {
super.onStop();
if (loadingDlg != null) {
if(loadingDlg.isShowing())
loadingDlg.dismiss();
loadingDlg = null;
}
}
リークウィンドウは通常、コンテキストにダイアログが表示され、ダイアログが適切に閉じられなかったためにコンテキストが突然強制的に閉じられたときに発生します。
これを修正するには、ウィンドウがエラーをリークする前にエラーを修正する必要があります。
AlertDialogが呼び出される前に場所と呼ばれるfinish()があったため、AlertDialogが呼び出される前にアクティビティが終了しました。 finish()を削除し、ユーザーがAlertDialogを使用して入力を完了し、ウィンドウリークが修正された後に配置しました。