android 活动已泄露窗口 com.android.internal.policy.impl.phonewindow$decorview 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12000940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android activity has leaked window com.android.internal.policy.impl.phonewindow$decorview Issue
提问by Ponmalar
I am working with Android application to show network error.
我正在使用 Android 应用程序来显示网络错误。
NetErrorPage.java
网络错误页面
package exp.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class NetErrorPage extends Activity implements OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.neterrorlayout);
Button reload=(Button)findViewById(R.id.btnReload);
reload.setOnClickListener(this);
showInfoMessageDialog("Please check your network connection","Network Alert");
}
public void onClick(View arg0)
{
if(isNetworkAvailable())
{
Intent myIntent = new Intent((Activity)NetErrorPage.this, MainActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
((Activity)NetErrorPage.this).startActivity(myIntent);
finish();
}
else
showInfoMessageDialog("Please check your network connection","Network Alert");
}
public void showInfoMessageDialog(String message,String title)
{
AlertDialog alertDialog = new AlertDialog.Builder(NetErrorPage.this).create();
alertDialog.setTitle("Network Alert");
alertDialog.setMessage(message);
alertDialog.setButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which)
{
dialog.cancel();
}
});
alertDialog.show();
}
private boolean isNetworkAvailable()
{
NetworkInfo ActiveNetwork;
@SuppressWarnings("unused")
String IsNetworkConnected;
@SuppressWarnings("unused")
String ConnectionType;
ConnectivityManager connectivitymanager;
connectivitymanager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
try
{
ActiveNetwork=connectivitymanager.getActiveNetworkInfo();
ConnectionType=ActiveNetwork.getTypeName();
IsNetworkConnected=String.valueOf(ActiveNetwork.getState());
return true;
}
catch(Exception error)
{
return false;
}
}
}
but i'm getting the error as below,
但我收到如下错误,
08-17 11:59:08.019: E/WindowManager(16460): Activity exp.app.NetErrorPage has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40534a18 that was originally added here
08-17 11:59:08.019: E/WindowManager(16460): android.view.WindowLeaked: Activity exp.app.NetErrorPage has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40534a18 that was originally added here
08-17 11:59:08.019: E/WindowManager(16460): at android.view.ViewRoot.<init>(ViewRoot.java:263)
08-17 11:59:08.019: E/WindowManager(16460): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
08-17 11:59:08.019: E/WindowManager(16460): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
08-17 11:59:08.019: E/WindowManager(16460): at android.view.Window$LocalWindowManager.addView(Window.java:424)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.Dialog.show(Dialog.java:241)
08-17 11:59:08.019: E/WindowManager(16460): at sync.directtrac.NetError.showInfoMessageDialog(NetErrorPage.java:114)
08-17 11:59:08.019: E/WindowManager(16460): at sync.directtrac.NetError.onCreate(NetErrorPage.java:26)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.ActivityThread.access00(ActivityThread.java:117)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
08-17 11:59:08.019: E/WindowManager(16460): at android.os.Handler.dispatchMessage(Handler.java:99)
08-17 11:59:08.019: E/WindowManager(16460): at android.os.Looper.loop(Looper.java:130)
08-17 11:59:08.019: E/WindowManager(16460): at android.app.ActivityThread.main(ActivityThread.java:3687)
08-17 11:59:08.019: E/WindowManager(16460): at java.lang.reflect.Method.invokeNative(Native Method)
08-17 11:59:08.019: E/WindowManager(16460): at java.lang.reflect.Method.invoke(Method.java:507)
08-17 11:59:08.019: E/WindowManager(16460): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-17 11:59:08.019: E/WindowManager(16460): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-17 11:59:08.019: E/WindowManager(16460): at dalvik.system.NativeStart.main(Native Method)
I have searched more... but i don't have any right idea to clear this.
我已经搜索了更多......但我没有任何正确的想法来清除这个。
What i want is, when loading this page, layout should be added and dialog should be shown.
我想要的是,在加载此页面时,应添加布局并显示对话框。
Please help me to clear this error
请帮我清除这个错误
Note:I have tried this also
注意:我也试过这个
@Override
protected void onResume() {
super.onResume();
runOnUiThread(new Runnable() {
public void run() {
showInfoMessageDialog("Please check your network connection","Network Alert");
}
});
}
回答by Ponmalar
Thank you Guys to give me many suggestions. Finally I got a solution. That is i have started the NetErrorPage intent two times. One time, i have checked the net connection availability and started the intent in page started event. second time, if the page has error, then i have started the intent in OnReceivedError event. So the first time dialog is not closed, before that the second dialog is called. So that i got a error.
谢谢你们给我很多建议。最后我得到了一个解决方案。那是我已经启动了两次 NetErrorPage 意图。有一次,我检查了网络连接可用性并在页面启动事件中启动了意图。第二次,如果页面有错误,那么我已经在 OnReceivedError 事件中启动了意图。所以第一次对话框没有关闭,在此之前第二个对话框被调用。所以我得到了一个错误。
Reason for the Error: I have called the showInfoMessageDialog method two times before closing the first one.
错误原因:在关闭第一个方法之前,我已经调用了两次 showInfoMessageDialog 方法。
Now I have removed the second call and Cleared error :-).
现在我已经删除了第二个调用并清除了错误:-)。
回答by Chirag
Change this dialog.cancel();
to dialog.dismiss();
将此更改dialog.cancel();
为dialog.dismiss();
The solution is to call dismiss()
on the Dialog
you created in NetErrorPage.java:114before exiting the Activity
, e.g. in onPause()
.
解决的办法是呼叫dismiss()
在Dialog
你中创建NetErrorPage.java:114退出之前Activity
,在如onPause()
。
Views have a reference to their parent Context
(taken from constructor argument). If you leave an Activity
without destroying Dialog
s and other dynamically created View
s, they still hold this reference to your Activity
(if you created with this as Context
: like new ProgressDialog(this)
), so it cannot be collected by the GC, causing a memory leak.
视图有对其父级的引用Context
(取自构造函数参数)。如果你在Activity
不销毁Dialog
s 和其他动态创建的View
s的情况下离开,它们仍然持有对你的这个引用Activity
(如果你用 this 作为Context
:like创建new ProgressDialog(this)
),所以它不能被 GC 收集,导致内存泄漏。
回答by CoolMind
In my case finish()
executed immediately after a dialog has shown.
在我的情况下finish()
,在显示对话框后立即执行。
回答by Haresh Chaudhary
Please try this Way And Let me know :
请尝试这种方式并让我知道:
Context mContext;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.neterrorlayout);
mContext=NetErrorPage.this;
Button reload=(Button)findViewById(R.id.btnReload);
reload.setOnClickListener(this);
showInfoMessageDialog("Please check your network connection","Network Alert");
}
public void showInfoMessageDialog(String message,String title)
{
new AlertDialog.Builder(mContext)
.setTitle("Network Alert");
.setMessage(message);
.setButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which)
{
dialog.cancel();
}
})
.show();
}
回答by nandeesh
The dialog needs to be started only after the window states of the Activity are initialized This happens only after onresume.
对话框需要在Activity的窗口状态被初始化之后才需要启动。这种情况只有在onresume之后才会发生。
So call
所以打电话
runOnUIthread(new Runnable(){
showInfoMessageDialog("Please check your network connection","Network Alert");
});
in your OnResume function. Do not create dialogs in OnCreate
Edit:
在您的 OnResume 函数中。不要在 OnCreate Edit 中创建对话框
:
use this
用这个
Handler h = new Handler();
h.postDelayed(new Runnable(){
showInfoMessageDialog("Please check your network connection","Network Alert");
},500);
in your Onresume instead of showonuithread
在你的 Onresume 而不是 showonuithread
回答by Carlos Rojas
@Override
protected void onPostExecute(final Boolean success) {
mProgressDialog.dismiss();
mProgressDialog = null;
setting the value null works for me
设置值 null 对我有用
回答by David Onyango
The way I got around this issue is by not calling intent within a dialog. **** use syntax applicable to activity or fragment accordingly
我解决这个问题的方法是不在对话框中调用意图。**** 相应地使用适用于活动或片段的语法
@Override
public void onClick(DialogInterface dialog, int which) {
checkvariable= true;
getActivity().finish();
}
@Override
public void onStop() {
super.onStop();
if (checkvariable) {
startActivity(intent);
}
}
回答by oguzhan
I got this error but it is resolved interesting. As first, i got this error at api level 17. When i call a thread (AsyncTask or others) without progress dialog then i call an other thread method again using progress dialog, i got that crash and the reason is about usage of progress dialog.
我收到了这个错误,但它的解决很有趣。首先,我在 api 级别 17 收到此错误。当我调用一个没有进度对话框的线程(AsyncTask 或其他线程)时,我再次使用进度对话框调用另一个线程方法,我遇到了崩溃,原因是进度对话框的使用.
In my case, there are two results that;
就我而言,有两个结果;
- I took
show();
method of progress dialog before first thread starts then i tookdismiss();
method of progress dialog before last thread ends.
- 我
show();
在第一个线程开始之前采用了进度对话框的方法,然后dismiss();
在最后一个线程结束之前采用了进度对话框的方法。
So :
所以 :
ProgresDialog progressDialog = new ...
//configure progressDialog
progressDialog.show();
start firstThread {
...
}
...
start lastThread {
...
}
//be sure to finish threads
progressDialog.dismiss();
- This is so strange but that error has an ability about destroy itself at least for me :)
- 这太奇怪了,但这个错误至少对我来说有自我毁灭的能力:)