Как выполнить некоторый код в асинхронном потоке пользовательского интерфейса Android? - PullRequest
8 голосов
/ 07 февраля 2012

Я новичок в разработке Android.Я работаю над Swing и SWT уже несколько лет.И Swing, и SWT имеют план выполнения кода в синхронизации и асинхронном потоке пользовательского интерфейса.Типичное использование - это выполнение некоторого затратного по времени персонала в одном потоке, а затем отображение результата в асинхронном потоке пользовательского интерфейса.

Итак, мой вопрос, есть ли в Android похожая страсть?Вот мой кодПараметр runnable - это некоторый код, занимающий много времени.Этот метод отображает диалоговое окно ожидания во время выполнения, затем ОЖИДАЕТ, чтобы показать тост после его завершения.Но Тост должен быть показан в потоке пользовательского интерфейса.Так как это сделать?

    public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {

    if (StringUtils.isEmpty(msg)) {
        msg = "processing...";
    }

    final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);

    // execute in a new thread instead of UI thread
    ThreadPoolUtil.execute(new Runnable() {

        public void run() {
            try {
                // some time-consume operation
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                waitingDialog.dismiss();
            }
            // TODO: How to display a Toast message here? execute some code in UI Thread.

        }

    });

}

И есть ли несколько слов о системе Android UI?Такие, как Thread-Safe, как поток работает вместе и так далее.Большое спасибо!

Ответы [ 6 ]

7 голосов
/ 07 февраля 2012

Есть несколько способов сделать это,

  • AsyncTask -

AsyncTask позволяет правильно и легко использовать поток пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в пользовательском интерфейсе поток без необходимости манипулировать потоками и / или обработчиками. Example for using AsyncTask

  • Сервис -

Сервис - это прикладной компонент, представляющий либо желание приложения выполнить более продолжительную операцию, пока взаимодействовать с пользователем или предоставлять функциональность для других приложения для использования. Example for Using Service.

  • IntentService -

IntentService является базовым классом для служб, которые обрабатывают асинхронный запросы (выраженные в виде содержания) по запросу. Клиенты отправляют запросы через вызовы startService (Intent); служба запускается по мере необходимости, обрабатывает каждое намерение по очереди, используя рабочий поток, и останавливает себя когда закончится работа. Example for using IntentService.

7 голосов
/ 07 февраля 2012

Вы можете использовать AsyncTask, как это.

Для вызова AsyncTask

new getAsynctask().execute("");

и вот класс для получения результата.

class getAsynctask extends AsyncTask<String, Long, Integer> {

    protected void onPreExecute() {
        super.onPreExecute();
        loading = ProgressDialog.show(Pass.this, null, "Please wait...");
    }
    protected Integer doInBackground(String... params) {
        try {
            // do your coding
            return null;
        } catch (Exception e) {
            return null;
        }

    }

    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        try {
            if (loading != null && loading.isShowing())
                loading.dismiss();
        } catch (Throwable t) {
            Log.v("this is praki", "loading.dismiss() problem", t);
        }
    }
}
2 голосов
/ 07 февраля 2012

Использовать обработчик:

static final int SHOW_TOAST = 0;
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {

    if (StringUtils.isEmpty(msg)) {
        msg = "processing...";
    }

    final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);

    // execute in a new thread instead of UI thread
    ThreadPoolUtil.execute(new Runnable() {

        public void run() {
            try {
                // some time-consume operation
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                waitingDialog.dismiss();
            }
           handler.sendMessage(handler.obtainMessage(SHOW_TOAST));

        }

    });

}

public Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SHOW_TOAST:
                //Toast here
                break;
        }
    }
};
2 голосов
/ 07 февраля 2012

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

initTask = new InitTask();
initTask.execute(this);


 protected class InitTask extends AsyncTask<Context, Integer, String> {     
        @Override
        protected String doInBackground(Context... params) {
            // Do the time comsuming task here 
            return "COMPLETE!";
        }

        // -- gets called just before thread begins
        @Override
        protected void onPreExecute() {         
            super.onPreExecute();

        }

        // -- called from the publish progress
        // -- notice that the datatype of the second param gets passed to this
        // method
        @Override
        protected void onProgressUpdate(Integer... values) {

        }

        // -- called if the cancel button is pressed
        @Override
        protected void onCancelled() {
            super.onCancelled();            
        }

        // -- called as soon as doInBackground method completes
        // -- notice that the third param gets passed to this method
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // Show the toast message here
        }
    }
2 голосов
/ 07 февраля 2012

Всякий раз, когда вы работаете с отдельным потоком, который не является вашим потоком пользовательского интерфейса, лучший способ - использовать Handler. Всякий раз, когда вы хотите пригласить пользователя в свою ветку, предположите прогресс, а затем отправьте сообщение в Handler. Внутри Handler вы можете обработать сообщение и написать фрагмент кода, чтобы изменить что-либо в пользовательском интерфейсе. Это предпочтительный способ для Android. см. эти ссылка1 , ссылка2 & ссылка3

1 голос
/ 07 февраля 2012

Статья Painless threading из ресурсов разработчика Android предлагает различные альтернативы в зависимости от конкретной версии SDK.

...