Не вдається створити обробник усередині потоку, який не викликав Looper.prepare () всередині AsyncTask для ProgressDialog


78

Я не розумію, чому я отримую цю помилку. Я використовую AsyncTask для запуску деяких процесів у фоновому режимі.

Я маю:

protected void onPreExecute() 
{
    connectionProgressDialog = new ProgressDialog(SetPreference.this);
    connectionProgressDialog.setCancelable(true);
    connectionProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    connectionProgressDialog.setMessage("Connecting to site...");
    connectionProgressDialog.show();

    downloadSpinnerProgressDialog = new ProgressDialog(SetPreference.this);
    downloadSpinnerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    downloadSpinnerProgressDialog.setMessage("Downloading wallpaper...");
}

Коли я потрапляю в doInBackground()залежність від стану, я:

[...]    
connectionProgressDialog.dismiss();
downloadSpinnerProgressDialog.show();
[...]

Щоразу, коли я намагаюся, downloadSpinnerProgressDialog.show()я отримую помилку.

Будь-які ідеї хлопці?

Відповіді:


106

Метод show()потрібно викликати з потоку інтерфейсу користувача (UI) , тоді як він doInBackground()працює в іншому потоці, що є основною причиною, за якою AsyncTaskбув розроблений.

Ви повинні зателефонувати show()або в, onProgressUpdate()або в onPostExecute().

Наприклад:

class ExampleTask extends AsyncTask<String, String, String> {

    // Your onPreExecute method.

    @Override
    protected String doInBackground(String... params) {
        // Your code.
        if (condition_is_true) {
            this.publishProgress("Show the dialog");
        }
        return "Result";
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        connectionProgressDialog.dismiss();
        downloadSpinnerProgressDialog.show();
    }
}

3
Це не зробило для мене фокусу, просто спробував "AlertDialog.Builder builder = new AlertDialog.Builder (context);" і додав конфігурацію конструктора. Спроба показати це всередині onProgressUpdate призводить до точно такої ж помилки. Будь-які ідеї?
ins0m

Дякую Костянтине, я не розумів, що ви можете перевизначити onProgressUpdate будь-яким типом змінної за допомогоюpubProgress (). Дійсно допомогло мені, просто оновити за допомогою тост-повідомлень.
дротовий зв'язок00

81

У мене була подібна проблема, але, прочитавши це запитання, я зрозумів, що можу працювати на потоці інтерфейсу користувача:

YourActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        alertDialog.show();
    }
});

Здається, це робить трюк для мене.


getActivity (). runOnUiThread (this :: mymethod); Подяка працювала дуже добре.
mortezahosseini

1

Мені теж було важко зробити цю роботу, рішенням для мене було використовувати як відповіді hyui, так і konstantin,

class ExampleTask extends AsyncTask<String, String, String> {

// Your onPreExecute method.

@Override
protected String doInBackground(String... params) {
    // Your code.
    if (condition_is_true) {
        this.publishProgress("Show the dialog");
    }
    return "Result";
}

@Override
protected void onProgressUpdate(String... values) {

    super.onProgressUpdate(values);
    YourActivity.this.runOnUiThread(new Runnable() {
       public void run() {
           alertDialog.show();
       }
     });
 }

}

Я думав, що все, що зроблено, onProgressUpdate()автоматично запускатиметься в потоці інтерфейсу користувача
Хтось десь

0
final Handler handler = new Handler() {
        @Override
        public void handleMessage(final Message msgs) {
        //write your code hear which give error
        }
        }

new Thread(new Runnable() {
    @Override
    public void run() {
    handler.sendEmptyMessage(1);
        //this will call handleMessage function and hendal all error
    }
    }).start();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.