dict1 = defaultdict(lambda: defaultdict(int))
cPickle.dump(dict(dict1), file_handle)
работал для меня
android.view.WindowManager$BadTokenException: Unable to add window"
Проблема:
Это исключение возникает, когда приложение пытается уведомить пользователя из фонового потока (AsyncTask), открыв диалоговое окно.
Если вы пытаетесь изменить пользовательский интерфейс из фонового потока (обычно из onPostExecute () AsyncTask), и если действие переходит к завершающему этапу, то есть прямому вызову finish (), пользователь нажимает кнопку «домой» или «назад» или активность
blockquote>Причина:
Причиной этого исключения является то, что, как говорится в сообщении об исключении, активность завершено, но вы пытаетесь отобразить диалог с контекстом готовой деятельности. Поскольку окно диалога для отображения среды андроида не отображается, вызывается это исключение.
blockquote>Решение:
Использовать метод
isFinishing()
, который вызывается Android чтобы проверить, находится ли эта деятельность в процессе отделки: будь то явный финиш () вызов или очистка активности, сделанная Android. Используя этот метод, очень легко избежать открытия диалога из фонового потока при завершении операции.Также поддерживать
blockquote>weak reference
для активности (а не сильную ссылку, чтобы активность можно было уничтожить, ), например.
private class chkSubscription extends AsyncTask<String, Void, String>{ private final WeakReference<login> loginActivityWeakRef; public chkSubscription (login loginActivity) { super(); this.loginActivityWeakRef= new WeakReference<login >(loginActivity) } protected String doInBackground(String... params) { //web service call } protected void onPostExecute(String result) { if(page.contains("error")) //when not subscribed { if (loginActivityWeakRef.get() != null && !loginActivityWeakRef.get().isFinishing()) { AlertDialog.Builder builder = new AlertDialog.Builder(login.this); builder.setCancelable(true); builder.setMessage(sucObject); builder.setInverseBackgroundForced(true); builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){ dialog.dismiss(); } }); builder.show(); } } } }
Обновление: если вы не выполняете какой-либо пользовательский интерфейс, используйте эту ссылку (например,
Токены окна:
Как следует из его названия, токен окна является специальным типом маркера Binder, который оконный менеджер использует для уникальной идентификации окна в системе. Ярлыки окна важны для безопасности, потому что они делают невозможным использование вредоносных приложений поверх окон других приложений. Менеджер окон защищает от этого, требуя от приложений передать токен своего приложения как часть каждого запроса на добавление или удаление окна. Если жетоны не совпадают, диспетчер окон отклоняет запрос и генерирует исключение BadTokenException. Без токенов окна этот необходимый шаг идентификации не был бы возможен, и оконный менеджер не смог бы защитить себя от вредоносных приложений.
blockquote>Реальный сценарий:
Когда приложение запускается в первый раз, ActivityManagerService создает специальный вид токена окна, называемый токеном окна приложения, который однозначно идентифицирует окно контейнера верхнего уровня приложения. Диспетчер активности предоставляет этот токен как для приложения, так и для диспетчера окон, и приложение отправляет токен в оконный менеджер каждый раз, когда хочет добавить на экран новое окно. Это обеспечивает безопасное взаимодействие между приложением и диспетчером окон (делая невозможным добавление окон поверх других приложений), а также упрощает диспетчеру активности непосредственные запросы к диспетчеру окон.
BLOCKQUOTE>
с этой идеей глобальных переменных, я сохранил экземпляр MainActivity в onCreate (); Глобальная переменная Android
public class ApplicationController extends Application {
public static MainActivity this_MainActivity;
}
и открыть диалоговое окно, подобное этому. он работал.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Global Var
globals = (ApplicationController) this.getApplication();
globals.this_MainActivity = this;
}
и в потоке открываю диалоговое окно, подобное этому.
AlertDialog.Builder alert = new AlertDialog.Builder(globals.this_MainActivity);
:)
У меня был диалог с функцией:
void showDialog(){
new AlertDialog.Builder(MyActivity.this)
...
.show();
}
Я получал эту ошибку, и мне просто нужно было проверить isFinishing()
перед вызовом этого диалогового окна, показывающего функцию.
if(!isFinishing())
showDialog();
if(!MyActivity.this.isFinishing())
? Если это неверно в MyActivity
– Bibaswann Bandyopadhyay
14 January 2017 в 11:29
Попробуйте следующее:
public class <class> extends Activity{
private AlertDialog.Builder builder;
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.<view>);
builder = new AlertDialog.Builder(<class>.this);
builder.setCancelable(true);
builder.setMessage(<message>);
builder.setInverseBackgroundForced(true);
//call the <className> class to execute
}
private class <className> extends AsyncTask<String, Void, String>{
protected String doInBackground(String... params) {
}
protected void onPostExecute(String result){
if(page.contains("error")) //when not subscribed
{
if(builder!=null){
builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){
dialog.dismiss();
if(!<condition>)
{
try
{
String pl = "";
mHelper.<flow>(<class>.this, SKU, RC_REQUEST,
<listener>, pl);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
});
builder.show();
}
}
}
}
Я создаю диалог в onCreate
и использую его с show
и hide
. Для меня основной причиной не было отклонение onBackPressed
, которое завершало активность Home
.
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Home.this.finish();
return;
}
}).create().show();
Я закончил Home Activity onBackPressed
, не закрывая / отклоняя мои диалоги.
Когда я отклонил мои диалоги, авария исчезла.
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
networkErrorDialog.dismiss() ;
homeLocationErrorDialog.dismiss() ;
currentLocationErrorDialog.dismiss() ;
Home.this.finish();
return;
}
}).create().show();
private boolean visible = false;
class chkSubscription extends AsyncTask<String, Void, String>
{
protected void onPostExecute(String result)
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setMessage(sucObject);
builder.setInverseBackgroundForced(true);
builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
dialog.dismiss();
}
});
AlertDialog myAlertDialog = builder.create();
if(visible) myAlertDialog.show();
}
@Override
protected String doInBackground(String... arg0)
{
// TODO Auto-generated method stub
return null;
}
}
@Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
visible = true;
}
@Override
protected void onStop()
{
visible = false;
super.onStop();
}
Возможная причина - контекст диалогового окна предупреждения. Вы можете завершить эту деятельность, чтобы ее попытка открыть в этом контексте, но которая уже закрыта. Попробуйте изменить контекст этого диалогового окна на первую операцию, потому что она не будет закончена до конца.
, например
, а не это.
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
попробуйте использовать
AlertDialog alertDialog = new AlertDialog.Builder(FirstActivity.getInstance()).create();