我正在使用ACRA报告应用程序崩溃.我收到一条View not attached to window manager错误消息,并认为我已通过pDialog.dismiss();在if语句中包装来修复它:
if (pDialog!=null)
{
if (pDialog.isShowing())
{
pDialog.dismiss();
}
}
Run Code Online (Sandbox Code Playgroud)
它减少了View not attached to window manager我收到的崩溃数量,但我仍然得到一些,我不知道如何解决它.
错误信息:
java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:425)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:327)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:83)
at android.app.Dialog.dismissDialog(Dialog.java:330)
at android.app.Dialog.dismiss(Dialog.java:312)
at com.package.class$LoadAllProducts.onPostExecute(class.java:624)
at com.package.class$LoadAllProducts.onPostExecute(class.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
代码段:
class LoadAllProducts extends AsyncTask<String, String, String>
{
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(CLASS.this);
pDialog.setMessage("Loading. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args)
{
// Building Parameters
doMoreStuff("internet");
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url)
{
// dismiss the dialog after getting all products
if (pDialog!=null)
{
if (pDialog.isShowing())
{
pDialog.dismiss(); //This is line 624!
}
}
something(note);
}
}
Run Code Online (Sandbox Code Playgroud)
表现:
<activity
android:name="pagename.CLASS"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
android:label="@string/name" >
</activity>
Run Code Online (Sandbox Code Playgroud)
我错过了什么来阻止这次崩溃?
era*_*tin 428
如何重现错误:
Settings -> Developer Options -> Don't keep Activities.AsyncTask正在执行和ProgressDialog正在显示.Android操作系统会在隐藏后立即销毁活动.当onPostExecute被称为Activity将处于"完成"状态并且ProgressDialog将不会附加Activity.
如何解决:
onPostExecute.ProgressDialogin onDestroy方法.否则,android.view.WindowLeaked将抛出异常.此异常通常来自活动完成时仍处于活动状态的对话框.试试这个固定代码:
public class YourActivity extends Activity {
private void showProgressDialog() {
if (pDialog == null) {
pDialog = new ProgressDialog(StartActivity.this);
pDialog.setMessage("Loading. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
}
pDialog.show();
}
private void dismissProgressDialog() {
if (pDialog != null && pDialog.isShowing()) {
pDialog.dismiss();
}
}
@Override
protected void onDestroy() {
dismissProgressDialog();
super.onDestroy();
}
class LoadAllProducts extends AsyncTask<String, String, String> {
// Before starting background thread Show Progress Dialog
@Override
protected void onPreExecute() {
showProgressDialog();
}
//getting All products from url
protected String doInBackground(String... args) {
doMoreStuff("internet");
return null;
}
// After completing background task Dismiss the progress dialog
protected void onPostExecute(String file_url) {
if (YourActivity.this.isDestroyed()) { // or call isFinishing() if min sdk version < 17
return;
}
dismissProgressDialog();
something(note);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Lib*_*bin 32
问题可能是Activity已经finished或在progress of finishing.
添加一个检查isFinishing,并仅在此时关闭对话框false
if (!YourActivity.this.isFinishing() && pDialog != null) {
pDialog.dismiss();
}
Run Code Online (Sandbox Code Playgroud)
isFinishing: 检查此活动是否在完成过程中,或者是因为您调用finish了该活动,或者是其他人已请求完成此活动.
对于Dialog在a中创建Fragment,我使用以下代码:
ProgressDialog myDialog = new ProgressDialog(getActivity());
myDialog.setOwnerActivity(getActivity());
...
Activity activity = myDialog.getOwnerActivity();
if( activity!=null && !activity.isFinishing()) {
myDialog.dismiss();
}
Run Code Online (Sandbox Code Playgroud)
我使用这种模式来处理一个Fragment可能脱离的情况Activity.
了解守则如何在这里工作:
调用异步任务后,异步任务在后台运行.这是可取的.现在这个Async任务有一个附加到Activity的进度对话框,如果你问怎么做,请看代码:
pDialog = new ProgressDialog(CLASS.this);
Run Code Online (Sandbox Code Playgroud)
您将Class.thisas上下文传递给参数.因此,"进度"对话框仍附加到活动.
现在考虑一下这个场景:如果我们尝试使用finish()方法完成活动,而异步任务正在进行中,那么您正试图访问附加到活动的资源,即progess bar活动不再存在的时间点.
因此你得到:
java.lang.IllegalArgumentException: View not attached to window manager
Run Code Online (Sandbox Code Playgroud)
.
解决方案:
1)确保在活动结束前取消或取消对话框.
2)完成活动,只有在关闭对话框后,即异步任务结束.
基于@erakitin答案,但也兼容Android版本<API级别17.可悲的是Activity.isDestroyed()仅支持API级别17,所以如果你的目标是像我一样的旧API级别,你将不得不自己检查一下.View not attached to window manager之后没有得到例外.
示例代码
public class MainActivity extends Activity {
private TestAsyncTask mAsyncTask;
private ProgressDialog mProgressDialog;
private boolean mIsDestroyed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (condition) {
mAsyncTask = new TestAsyncTask();
mAsyncTask.execute();
}
}
@Override
protected void onResume() {
super.onResume();
if (mAsyncTask != null && mAsyncTask.getStatus() != AsyncTask.Status.FINISHED) {
Toast.makeText(this, "Still loading", Toast.LENGTH_LONG).show();
return;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mIsDestroyed = true;
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
public class TestAsyncTask extends AsyncTask<Void, Void, AsyncResult> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = ProgressDialog.show(MainActivity.this, "Please wait", "doing stuff..");
}
@Override
protected AsyncResult doInBackground(Void... arg0) {
// Do long running background stuff
return null;
}
@Override
protected void onPostExecute(AsyncResult result) {
// Use MainActivity.this.isDestroyed() when targeting API level 17 or higher
if (mIsDestroyed)// Activity not there anymore
return;
mProgressDialog.dismiss();
// Handle rest onPostExecute
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
@Override
public void onPause() {
super.onPause();
if(pDialog != null)
pDialog .dismiss();
pDialog = null;
}
Run Code Online (Sandbox Code Playgroud)
参考这个。
| 归档时间: |
|
| 查看次数: |
116280 次 |
| 最近记录: |