활동이 원래 추가 된 창을 유출했습니다.
이 오류는 무엇이며 왜 발생합니까?
05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850): at dalvik.system.NativeStart.main(Native Method)
활동을 종료 한 후 대화 상자를 표시하려고합니다.
[편집하다]
이 질문은 안드로이드 개발자를위한 구글의 상위 검색 중 하나입니다. 따라서 댓글에서 몇 가지 중요한 포인트를 추가하면 댓글에 대한 깊이있는 대화없이 향후 조사자에게 더 도움이 될 수 있습니다.
답변 1 :
활동을 종료 한 후 대화 상자를 표시하려고합니다.
답변 2
이 오류는 일부 상황에서 약간의 오해의 소지가있을 수 있습니다. '진짜'예외는 로그에서 조금 더 일찍
답변 3
액티비티를 종료하기 전에 생성 한 Dialog 인스턴스 (예 : onPause () 또는 onDestroy ())에서 dismiss ()를 호출합니다.
해결책 은를 종료하기 전에 에서 생성 한를 호출 dismiss()
하는 Dialog
것 입니다 . 모든 s & 는를 떠나기 전에 닫아야합니다 .viewP.java:183
Activity
onPause()
Window
Dialog
Activity
를 사용하는 경우 AsyncTask
해당 로그 메시지가 속일 수 있습니다. 로그에서 찾아 보면 다른 오류를 발견 할 수 있습니다. 아마도 귀하의 doInBackground()
방법 에서 하나는 AsyncTask
전류 Activity
를 날려 버리는 것입니다. 따라서 일단 AsyncTask
다시 돌아 오면 나머지는 알 수 있습니다. 일부 다른 사용자는 이미 여기에서 설명했습니다 :-)
.NET hide()
대신 실수로 호출하여이 오류를 트리거 dismiss()
했습니다 AlertDialog
.
예를 들어 switch 문에서 break call 문을 놓친 경우 실수로 finish()
를 표시 한 후 호출하여 단순 / 멍청한 실수로이 예외를 얻을 수 있습니다 AlertDialog
.
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.new_button:
openMyAlertDialog();
break; <-- If you forget this the finish() method below
will be called while the dialog is showing!
case R.id.exit_button:
finish();
break;
}
}
finish()
방법은 종료됩니다 Activity
,하지만이 AlertDialog
여전히 표시됩니다!
따라서 코드를 열심히 쳐다보고 잘못된 스레딩 문제 나 복잡한 코딩 등을 찾을 때 나무의 숲을 놓치지 마십시오. 때로는 누락 된 break 문처럼 단순하고 멍청한 것일 수 있습니다. :)
이 문제는 활동을 종료 한 후 대화 상자를 표시하려고 할 때 발생합니다.
다음 코드를 작성하여이 문제를 해결했습니다.
@Override
public void onDestroy(){
super.onDestroy();
if ( progressDialog!=null && progressDialog.isShowing() ){
progressDialog.cancel();
}
}
기본적으로 어떤 클래스에서 progressDialog를 시작했는지 onDestroy 메서드를 재정의하고 이런 방식으로 수행하십시오. "액티비티 창에서 누수"문제를 해결했습니다.
이 질문에 대한 답은 모두 정확했지만 실제로 그 이유를 이해하기에는 약간 혼란 스러웠습니다. 약 2 시간 동안 놀아 본 후이 오류 (제 경우)의 이유가 저를 때렸습니다.
다른 답변을 읽었을 때 has X has leaked window DecorView@d9e6131[]
오류는 앱이 닫힐 때 대화 상자가 열렸다는 것을 이미 알고 있습니다. 그런데 왜?
대화 상자가 열려있는 동안 다른 이유로 인해 앱이 다운되었을 수 있습니다.
이로 인해 코드의 일부 버그로 인해 앱이 닫히고 다른 오류로 인해 앱이 닫힌 것과 동시에 대화 상자가 열린 상태로 유지됩니다.
따라서 논리를 살펴보십시오. 첫 번째 오류를 해결하면 두 번째 오류가 저절로 해결됩니다.
하나의 오류로 인해 다른 오류가 발생하여 DOMINOS와 같은 다른 오류가 발생합니다!
나는 최근에 같은 문제에 직면했습니다.
이 문제의 원인은 대화 상자가 닫히기 전에 활동이 닫히기 때문입니다. 위와 같은 일이 발생하는 데는 여러 가지 이유가 있습니다. 위의 게시물에 언급 된 내용도 정확합니다.
스레드에서 예외를 던지는 함수를 호출했기 때문에 상황이 발생했습니다. 그 때문에 창이 닫히고 예외가 발생했습니다.
활동이 파괴되면 대화 상자 닫기
@Override
protected void onDestroy()
{
super.onDestroy();
if (pDialog!=null && pDialog.isShowing()){
pDialog.dismiss();
}
}
이것이 도움이 될 수 있습니다.
if (! isFinishing()) {
dialog.show();
}
나는 똑같은 모호한 오류 메시지가 있었고 그 이유를 알지 못했습니다. 이전 답변의 단서가 주어지면 GUI가 아닌 mDialog.finish () 호출을 mDialog.dismiss ()로 변경하고 오류가 사라졌습니다. 이것은 내 위젯의 동작에 영향을 미치지는 않았지만 당황스럽고 중요한 메모리 누수를 표시했을 수 있습니다.
내 비디오 플레이어 응용 프로그램에서 이러한 로그를 얻었습니다. 이 메시지는 비디오 플레이어가 닫힌 동안 발생했습니다. 흥미롭게도, 나는 무작위 방식으로 몇 번의 실행으로 이러한 로그를 한 번 얻었습니다. 또한 내 응용 프로그램은 progressdialog
. 마지막으로 아래 구현을 통해이 문제를 해결했습니다.
@Override
protected void onPause()
{
Log.v("MediaVideo", "onPause");
super.onPause();
this.mVideoView.pause();
this.mVideoView.setVisibility(View.GONE);
}
@Override
protected void onDestroy()
{
Log.v("MediaVideo", "onDestroy");
super.onDestroy();
}
@Override
protected void onResume()
{
Log.v("MediaVideo", "onResume");
super.onResume();
this.mVideoView.resume();
}
OnPause
with 호출을 재정의하고 로 mVideoView.pause()
설정 visibility
합니다 GONE
. 이렇게하면 " Activity has leaked window
"로그 오류 문제를 해결할 수 있습니다.
나는 같은 문제가 있었고이 페이지를 발견했으며 내 상황이 다른 동안 경고 상자를 정의하기 전에 블록 finish
에서 호출 if
했습니다.
따라서 단순히 전화를 걸면dismiss
작동하지 않지만 (아직 만들어지지 않았기 때문에) Alex Volovoy의 답변 을 읽고 그것이 원인이 된 경고 상자 임을 깨달은 후에 . 해당 if
블록 내부의 완료 직후에 return 문을 추가하려고 시도 했으며 문제가 해결되었습니다.
나는 당신이 끝내라고 불렀을 때 모든 것을 멈추고 바로 거기에서 끝났다고 생각했지만 그렇지 않습니다. 코드 블록의 끝으로 이동 한 다음 완료됩니다.
따라서 일부 코드를 수행하기 전에 때때로 완료되는 상황을 구현하려면 종료 직후에 return 문을 입력해야합니다. 당신이 그것을 부른 곳이 아닌 코드 블록. 그래서 이상한 오류가 모두 발생했습니다.
private picked(File aDirectory){
if(aDirectory.length()==0){
setResult(RESULT_CANCELED, new Intent());
finish();
return;
}
AlertDialog.Builder alert= new AlertDialog.Builder(this); // Start dialog builder
alert
.setTitle("Question")
.setMessage("Do you want to open that file?"+aDirectory.getName());
alert
.setPositiveButton("OK", okButtonListener)
.setNegativeButton("Cancel", cancelButtonListener);
alert.show();
}
If you don't put the return right after I called finish in there, it will act as if you have called it after the alert.show();
and hence it would say that the window is leaked by finishing just after you made the dialog appear, even though that's not the case, it still think it is.
I thought I'd add this as here as this shows the finish command acted differently then I thought it did and I'd guess there are other people who think the same as I did before I discovered this.
This is not the answer to the question but it's relevant to the topic.
If the activity has defined an attribute in the Manifest
android:noHistory="true"
then after executing onPause(), the context of activity is lost. So all the view's using this context might give this error.
Not only try to show an alert but it can also be invoked when you finish a particular instance of activity and try to start new activity/service or try to stop it.
Example:
OldActivity instance;
oncreate() {
instance=this;
}
instance.finish();
instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));
Had the problem where I finished an Activity when a ProgressDialog was still shown.
So first hide the Dialog and then finish the activity.
Try this code:
public class Sample extends Activity(){
@Override
public void onCreate(Bundle instance){
}
@Override
public void onStop() {
super.onStop();
progressdialog.dismiss(); // try this
}
}
This can be if you have an error at doInBackground()
function and have this code.
Try to add dialog at last. At first check and fix doInBackground()
function
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(CreateAccount.this);
pDialog.setMessage("Creating Product..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String...args) {
ERROR CAN BE IS HERE
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
pDialog.dismiss();
This happened to me when i am using ProgressDialog
in AsyncTask
. Actually i am using hide()
method in onPostExecute
. Based on the answer of @Alex Volovoy i need to use dismiss()
with ProgressDialog
to remove it in onPostExecute and its done.
progressDialog.hide(); // Don't use it, it gives error
progressDialog.dismiss(); // Use it
The "Activity has leaked window that was originally added...
" error occurs when you try show an alert after the Activity
is effectively finished
.
You have two options AFAIK:
- Rethink the login of your alert: call
dismiss()
on thedialog
before actually exiting your activity. - Put the
dialog
in a different thread and run it on thatthread
(independent of the currentactivity
).
Generally this issue occurs due to progress dialog : you can solve this by using any one of the following method in your activity:
// 1):
@Override
protected void onPause() {
super.onPause();
if ( yourProgressDialog!=null && yourProgressDialog.isShowing() )
{
yourProgressDialog.cancel();
}
}
// 2) :
@Override
protected void onDestroy() {
super.onDestroy();
if ( yourProgressDialog!=null && yourProgressDialog.isShowing()
{
yourProgressDialog.cancel();
}
}
You have to make Progressdialog
object in onPreExecute
method of AsyncTask
and you should dismiss
it on onPostExecute
method.
Best solution is just add dialog in try catch and dismiss dialog when exception occur
Just use below code
try {
dialog.show();
} catch (Exception e) {
dialog.dismiss();
}
In my case, the reason was that I forgot to include a permission in the Android manifest file.
How did I find out? Well, just like @Bobby says in a comment beneath the accepted answer, just scroll further up to your logs and you'll see the first reason or event that really threw the Exception. Apparently, the message "Activity has leaked window that was originally added" is only an Exception that resulted from whatever the first Exception is.
Try below code , it will work any time you will dismiss the progress dialogue and it will see whether its instance is available or not.
try {
if (null != progressDialog && progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
} catch (Exception e) {
e.printStackTrace();
}
Window leaked exceptions have two reasons:
1) showing the dialog when Activity Context doesn't exists, to solve this you should show the dialog only you are sure Activity exists:
if(getActivity()!= null && !getActivity().isFinishing()){
Dialog.show();
}
2) not dismiss the dialog appropriately, to solve use this code:
@Override
public void onDestroy(){
super.onDestroy();
if ( Dialog!=null && Dialog.isShowing() ){
Dialog.dismiss();
}
}
가장 좋은 해결책은 보여주기 전에 이것을 progressbar
넣거나progressDialog
if (getApplicationContext().getWindow().getDecorView().isShown()) {
//Show Your Progress Dialog
}
코드 어딘가에서 발생한 일부 예외로 인해 활동이 예기치 않게 종료되지 않는지 확인하십시오. 일반적으로 활동이 doinBackground 메서드에서 강제 종료에 직면 한 다음 asynctask가 onPostexecute 메서드로 반환 될 때 비동기 작업에서 발생합니다.
if (mActivity != null && !mActivity.isFinishing() && mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
나에 따르면 문제는 활동이 완료된 직후 대화 상자를 호출하려고한다는 것이므로 나에 따라 Handler를 사용하여 약간의 지연을 줄 수 있으며 문제는 다음과 같이 해결됩니다.
Handler handler=new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
dialog.show();
//or
dialog.dismiss();
}
},100);
참고 URL : https://stackoverflow.com/questions/2850573/activity-has-leaked-window-that-was-originally-added
'development' 카테고리의 다른 글
visible : hidden과 display : none의 차이점은 무엇입니까? (0) | 2020.09.27 |
---|---|
Docker 컨테이너 내부에서 머신의 로컬 호스트에 어떻게 연결합니까? (0) | 2020.09.27 |
T를 열거 형으로 제한하는 일반 메서드 만들기 (0) | 2020.09.27 |
.gitignore for Visual Studio 프로젝트 및 솔루션 (0) | 2020.09.27 |
HTML에서 "role"속성의 목적은 무엇입니까? (0) | 2020.09.27 |