Как вернуть AlertDialogs из универсального класса в Android? - PullRequest
1 голос
/ 15 ноября 2010

В общедоступном классе, который не расширяет другие классы, я занимаюсь оценкой и хочу вернуть диалог, если что-то нужно сообщить пользователю.

Я использую AsyncTask для запуска метода экземпляра этого класса из основного интерфейса:

private OnlineActivities onlineActivities = new OnlineActivities();

new DoOnlineActivity().execute(getApplicationContext());

private class DoOnlineStuff extends AsyncTask<Context, Integer, Dialog> {
    @Override
    protected Dialog doInBackground(Context... params) {
        return onlineActivities.start(params[0]);
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        Log.v(RuntimeVars.getMyName(), "AsyncOnlineTask in progess");
    }

    @Override
    protected void onPostExecute(Dialog result) {
        if (result != null)
            result.show();
    }
}

Теперь метод public Dialog start() для OnlineActivities.java создает диалог с использованием контекста, назначенного через его параметр.

Когда диалог возвращается к onPostExecute, я получаю следующее исключение

11-14 23:53:43.303: ERROR/AndroidRuntime(1320): FATAL EXCEPTION: main
11-14 23:53:43.303: ERROR/AndroidRuntime(1320): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.view.ViewRoot.setView(ViewRoot.java:509)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.app.Dialog.show(Dialog.java:241)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at info.myProject.messaging.ConversationList$DoOnlineActivity.onPostExecute(ConversationList.java:245)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at info.myProject.messaging.ConversationList$DoOnlineActivity.onPostExecute(ConversationList.java:1)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.os.AsyncTask.finish(AsyncTask.java:417)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.os.AsyncTask.access$300(AsyncTask.java:127)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.os.Looper.loop(Looper.java:123)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at android.app.ActivityThread.main(ActivityThread.java:4627)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at java.lang.reflect.Method.invoke(Method.java:521)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-14 23:53:43.303: ERROR/AndroidRuntime(1320):     at dalvik.system.NativeStart.main(Native Method)

Полагаю, я не могу использовать подобный контекст. Но что будет альтернативой? Как я могу отдать на аутсорсинг некоторые базовые вещи, которые мне всегда нужно делать, даже некоторые общие диалоги?

Нужно ли вместо этого использовать пользовательские намерения?

Ответы [ 2 ]

1 голос
/ 15 ноября 2010

Не делай этого.Передайте контекст в конструктор.А затем покажите упражнение в фоновом режиме, а затем очистите его после.

new DoOnlineActivity().execute(getApplicationContext());

private class DoOnlineStuff extends AsyncTask<Void, Integer, Dialog> {

    Context ctx;
    Dialog dialg

    public DoOnlineStuff(Context ctx){

    this.ctx = ctx;

}


    @Override
    protected void onPreExecute(){
    dialg = createdialog;
    dialog.show()
}

    @Override
    protected Dialog doInBackground(Void... void) {
        // Do stuff in background
        publishProgress(0);
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        Log.v(RuntimeVars.getMyName(), "AsyncOnlineTask in progess");
    }

    @Override
    protected void onPostExecute(Dialog result) {
        dialog.dismiss()

}
0 голосов
/ 16 ноября 2010

Я получил часть этого, чтобы работать. Проблема заключалась в использовании getApplicationContext(). Android SDK состояния

Возвращает контекст одного глобального объекта Application текущего процесса.

Полагаю, этот контекст отличается от контекста фактической деятельности.

Таким образом, диалоговое окно отображается, когда я использую this вместо getApplicationContext():

private OnlineActivities onlineActivities = new OnlineActivities();

new DoOnlineActivity(this).execute();

private class DoOnlineStuff extends AsyncTask<Void, Integer, Dialog> {
    Context ctx;
    Dialog dialog;

    public DoOnlineActivity(Context ctx){
        this.ctx = ctx;
    }

    @Override
    protected Dialog doInBackground(Void... params) {
        return onlineActivities.start(ctx);
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        Log.v(RuntimeVars.getMyName(), "AsyncOnlineTask in progess");
    }

    @Override
    protected void onPostExecute(Dialog result) {
        if (result != null) {
            dialog = result;
            dialog.show();
        }
    }
}

НО: теперь кнопка, которую я создал в диалоге, ничего не сделает. Я полагаю, что OnClickListener() в моем диалоге не отвечает в контексте моего основного интерфейса:

final View layout = View.inflate(ctx, R.layout.dialog_phonenumber_request, null);
((TextView) layout.findViewById(R.id.label)).setText(ctx.getString(R.string.dialog_insert_self_phonenumber_request_text1));

final EditText savedPhoneNumber = ((EditText) layout.findViewById(R.id.phonenum));
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setIcon(0);
builder.setTitle(ctx.getString(R.string.dialog_insert_self_phonenumber_request_title));

builder.setPositiveButton(ctx.getString(R.string.save),
    new Dialog.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            String toSavePhoneNumber = savedPhoneNumber.getText().toString().trim();

            Database thisDBHandler = new Database(ctx);
            thisDBHandler.open();
            thisDBHandler.insertSetting(RuntimeVars.getDBPhoneNumberName(), toSavePhoneNumber);
            thisDBHandler.close();
        }
    }
);
builder.setView(layout);
return builder.create();

Таким образом, последний шаг должен сказать OnClickListener(), какой контекст использовать. Но как это можно сделать? new Dialog.OnClickListener() не будет принимать никаких параметров о контексте?

Спасибо!
S.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...