Я использую ACRA, чтобы сообщить о сбоях приложения. Я получал View not attached to window manager
сообщение об ошибке и думал, что исправил его, pDialog.dismiss();
заключив в оператор if:
if (pDialog!=null)
{
if (pDialog.isShowing())
{
pDialog.dismiss();
}
}
Это уменьшило количество 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)
Фрагмент кода:
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);
}
}
Manifest:
<activity
android:name="pagename.CLASS"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
android:label="@string/name" >
</activity>
Чего мне не хватает, чтобы остановить этот сбой?
AsyncTask
объявлен внутриActivity
илиFragment
?Ответы:
Как воспроизвести ошибку:
Settings -> Developer Options -> Don't keep Activities
.AsyncTask
выполнения иProgressDialog
отображения.ОС Android уничтожит активность, как только она будет скрыта. Когда
onPostExecute
вызывается,Activity
он будет в «завершающем» состоянии иProgressDialog
не будет привязан кActivity
.Как это исправить:
onPostExecute
методе.ProgressDialog
вonDestroy
методе. В противном случаеandroid.view.WindowLeaked
будет выдано исключение. Это исключение обычно происходит из диалогов, которые все еще активны, когда действие заканчивается.Попробуйте этот фиксированный код:
источник
isDestroyed()
overisFinishing()
на всех API для этой конкретной цели?isFinishing()
гарантированно не будет,true
если действие уничтожено системой, см. Документацию по действиям .// or call isFinishing() if min sdk version < 17
, он столкнется с тем же исключением. Таким образом, нам нужно другое решение, чем этот ответ для приложений, работающих на API <17.myActivityWeakReference.get() != null && !myActivityWeakReference.get().isFinishing()
Проблема может заключаться в том, что
Activity
былfinished
или вprogress of finishing
.Добавить проверку
isFinishing
и закрыть диалог только тогда, когда этоfalse
isFinishing: Проверьте, находится ли это действие в процессе завершения, потому что вы вызвали
finish
его или кто-то еще запросил его завершение.источник
Для
Dialog
созданного вFragment
я использую следующий код:Я использую этот шаблон, чтобы иметь дело со случаем, когда a
Fragment
может быть отсоединен отActivity
.источник
Посмотрите, как работает Код здесь:
После вызова асинхронной задачи асинхронная задача запускается в фоновом режиме. это желательно. Теперь у этой асинхронной задачи есть диалоговое окно прогресса, которое прикреплено к Activity, если вы спросите, как просмотреть код:
Вы передаете в
Class.this
качестве контекста аргумент. Таким образом, диалог «Ход выполнения» все еще привязан к действию.Теперь рассмотрим сценарий: если мы пытаемся завершить действие, используя метод finish (), когда выполняется асинхронная задача, это точка, где вы пытаетесь получить доступ к ресурсу, прикрепленному к действию, т.е.
progress bar
Когда действия больше нет там.Отсюда вы получаете:
Решение этого:
1) Убедитесь, что диалоговое окно закрыто или отменено до завершения действия.
2) Завершите действие, только после закрытия диалогового окна, то есть асинхронная задача завершена.
источник
Activity
; Android может закончить это в любое время. Итак, № 2 не имеет смысла.Основано на ответе @erakitin, но также совместимо для версий Android <уровень API 17. К сожалению, Activity.isDestroyed () поддерживается только начиная с уровня API 17, поэтому, если вы нацеливаетесь на более старый уровень API, как и я, вам придется проверьте это сами.
View not attached to window manager
После этого не было исключения.Пример кода
источник
передайте это .
источник
Переопределить onConfigurationChanged и закрыть диалоговое окно прогресса. Если диалоговое окно прогресса создается в книжной ориентации и отклоняется в альбомной, то при этом выдается ошибка «Вид не прикреплен к диспетчеру окон».
Также остановите индикатор выполнения и остановите асинхронную задачу в методах onPause (), onBackPressed и onDestroy.
источник
Переопределите onDestroy of the Activity и закройте диалог и сделайте его пустым
источник
Во-первых, причина сбоя в том, что индекс decorView равен -1, мы можем знать это по исходному коду Android, есть фрагмент кода:
Таким образом, мы получаем следующее разрешение, просто оцениваем индекс decorView, если он больше 0, затем продолжаем или просто возвращаем и прекращаем выполнение, кодируйте следующим образом:
источник
Пересмотрите
dismiss()
метод следующим образом:Чтобы воспроизвести проблему, просто завершите действие, прежде чем закрыть диалоговое окно.
источник
лучшее решение. Проверьте, что первый контекст является контекстом действия или контекстом приложения, если контекст действия тогда только проверяет, завершена ли активность, или нет, затем вызовите
dialog.show()
илиdialog.dismiss();
Если вы хотите добавить больше проверок, то добавьте
dialog.isShowing()
илиdialog !-null
используйте&&
условие.источник
Эта проблема связана с тем, что ваша деятельность завершается до вызова функции dismiss. Обработайте исключение и проверьте ваш журнал ADB для точной причины.
источник
У меня есть способ воспроизвести это исключение.
Я использую 2
AsyncTask
. Один выполняет длинное задание, а другой - короткое задание. После выполнения короткого задания позвонитеfinish()
. Когда долгое задание завершено и звонитеDialog.dismiss()
, оно вылетает.Вот мой пример кода:
Вы можете попробовать это и выяснить, как лучше всего решить эту проблему. Из моего исследования есть как минимум 4 способа это исправить:
isFinishing()
чтобы проверить состояние деятельностиAsyncTask.cancel(false)
вonDestroy()
. Это предотвратит выполнение асинхронной задачи,onPostExecute()
но выполнит ееonCancelled()
.Примечание:
onPostExecute()
все равно будет выполняться даже при вызовеAsyncTask.cancel(false)
на более старой ОС Android, такой как Android 2.XXВы можете выбрать лучший для вас.
источник
Может быть, вы инициализируете pDialog глобально, затем удалите его и инициализируйте ваш вид или диалог локально. У меня та же проблема, я сделал это, и моя проблема решена. Надеюсь, это сработает для тебя.
источник
мы также отклонили наш диалог о
onPause
методе илиonDestroy
методеисточник