ProgressDialog.show() - Activity 已泄露窗口
Posted
技术标签:
【中文标题】ProgressDialog.show() - Activity 已泄露窗口【英文标题】:ProgressDialog.show() - Activity has leaked window 【发布时间】:2020-06-13 23:47:54 【问题描述】:我已经为我所有需要 ProgressDialogs 的后台进程创建了一个 AsyncTask 类,并将它放在我的 Utils
java 类中,但是当我尝试调用它时,它在 ProgressDialog 的 show()
方法上出现了描述的错误。
这里是 Utils 类中的 AsyncTask 类:
public static class BackgroundTask extends AsyncTask<Void, Void, Void>
private WeakReference<Context> context;
private ProgressDialog progressDialog;
private String message;
private Runnable doInBackground;
public BackgroundTask(Context context, String message, Runnable doInBackground)
this.context = new WeakReference<>(context);
this.message = message;
this.doInBackground = doInBackground;
@Override
protected void onPreExecute()
if (context == null)
return;
progressDialog = new ProgressDialog(context.get(), R.style.dialogStyle);
progressDialog.setMessage(message);
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setIndeterminate(false);
progressDialog.show();
@Override
protected Void doInBackground(Void... params)
doInBackground.run();
return null;
@Override
protected void onPostExecute(Void result)
if(progressDialog != null)
progressDialog.dismiss();
progressDialog = null;
这就是我在MainActivity
上的称呼:
new Utils.BackgroundTask(this, "Loading...",() ->
// Something heavy to do
).execute();
什么问题,我该如何解决。提前致谢。
编辑
在活动中加载片段可能有问题吗?这正是我在我的MainActivity
中所说的:
new Utils.BackgroundTask(this, "Loading...",() ->
String codeResponse = NetworkConnection.get(this, NetworkConnection.BaseUrl + "sms/code.php?mobile=0" + phoneNumber);
if(codeResponse != null)
this.code = new Gson().fromJson(codeResponse, CheckCodeModel.class).getCode();
Toast.makeText(this, "Code is :" + code + ":", Toast.LENGTH_SHORT).show();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_login_fragmentHolder,new LoginCheckCodeFragment(),"CheckCode");
transaction.addToBackStack("CheckCode");
transaction.commit();
).execute();
【问题讨论】:
把它放到你的异步任务中 if(progressDialog!=null && progressDialog.isShowing())progressDialog.dismiss();) @AmanB。我做了,但问题仍然存在。 在上下文中,你必须使用“getApplicationContext()”而不是传递“this”。 @AmanB。我也尝试过,但ProgressDialog
在这种情况下更快崩溃。 Caused by: android.view.InflateException: Binary XML file line #44: Error inflating class com.android.internal.widget.DialogTitle
检查您的 xml 文件第 44 行。那里有什么?
【参考方案1】:
为了正确使用WeakReferences,你需要检查底层值是否为null,而不是你的弱引用对象。
即不是:
if (context == null) // this is always `false` as you instantiate in your constructor
但是:
if (context.get() == null)
您可能自己发现了一个更清晰的变量名,可能使用weakRefToContext
而不是context
。
【讨论】:
【参考方案2】:通过将我的部分代码放入 runOnUiThread()
方法来修复它:
new Utils.BackgroundTask(LoginActivity.this, "Loading...",() ->
String codeResponse = NetworkConnection.get(this, NetworkConnection.BaseUrl + "sms/code.php?mobile=0" + phoneNumber);
if(codeResponse != null)
runOnUiThread(() ->
this.code = new Gson().fromJson(codeResponse, CheckCodeModel.class).getCode();
Toast.makeText(this, "Code is :" + code + ":", Toast.LENGTH_SHORT).show();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_login_fragmentHolder,new LoginCheckCodeFragment(),"CheckCode");
transaction.addToBackStack("CheckCode");
transaction.commit();
);
).execute();
感谢@Aman B. 和 @Blundell。
【讨论】:
您可以通过支持我的答案和/或将其标记为答案来感谢我,这就是网站的运作方式:-)以上是关于ProgressDialog.show() - Activity 已泄露窗口的主要内容,如果未能解决你的问题,请参考以下文章
关于ProgressDialog.show抛出android.view.WindowManager$BadTokenException: Unable to add window