#android #multithreading #timer #android-asynctask #timertask
#Android #многопоточность #таймер #android-asynctask #timertask
Вопрос:
Я пытаюсь выполнить задачу (т.е. загружать данные из текстового файла) асинхронно и повторно в указанное время (т. Е. каждые несколько секунд, хотя эта скорость может меняться во время выполнения).
Я провел некоторое исследование и решил, что для этого потребуется либо AsyncTask, либо отдельный поток. Я решил использовать AsyncTask для простоты.
Теперь мне нужно выполнить эту асинхронную задачу в соответствии с повторяющимся расписанием таймера. Я считаю, что я должен использовать таймер и TimerTask.
Приведенный ниже код представляет собой простую форму того, чего я пытаюсь достичь. Когда я пытаюсь запустить этот код с помощью эмулятора Android (через Eclipse IDE), я получаю следующее сообщение: «Извините! Приложение неожиданно остановилось. Пожалуйста, попробуйте еще раз.»
Я хотел бы знать, где возникает проблема и как я могу ее исправить. Спасибо!
public class Sample extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SimpleTimerTask myTimerTask = new SimpleTimerTask();
long delay = 0;
long period = 5000;
Timer myTimer = new Timer();
myTimer.schedule(myTimerTask, delay, period);
}
private class SimpleAsyncTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
}
private class SimpleTimerTask extends TimerTask {
public void run() {
new SimpleAsyncTask().execute();
}
}
}
РЕДАКТИРОВАТЬ: Вот сообщения LogCat, которые кажутся актуальными
ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: таймер-0
java.lang.Ошибка ExceptionInInitializerError
в …
Вызвано: java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызывал Looper.prepare()
в …
Комментарии:
1. Что говорит журнал в logcat? Вероятно, вы найдете там stacktrace, и это указывает на вашу проблему.
2. @Kaj — Это очень полезный комментарий (по крайней мере, для начинающих разработчиков Android, таких как я). Я даже не знал, что такое LogCat, но теперь я вижу его значение для отладки / отслеживания ошибок.
Ответ №1:
Вы делаете этот способ сложнее, чем это должно быть. TimerTask
Уже выполняется в своем собственном потоке, поэтому вам не нужно использовать AsyncTask
просто поместите код, который вы хотите запустить в TimerTask.run()
метод.
Комментарии:
1. Интересно. Мне определенно нравится это решение больше, поскольку оно проще. Мне просто нужно выяснить, как я могу обновить пользовательский интерфейс из потока TimerTask сейчас … есть идеи? Спасибо за вашу помощь!
2. Вы можете передать
Handler
для отправкиMessages
в поток пользовательского интерфейса.
Ответ №2:
Существует серьезное ограничение использования timertask с asynctask, если вы хотите обновить пользовательский интерфейс из метода onPostExecute. Таймер запускается в отдельном потоке, поэтому вам нужно найти способ запустить асинхронную задачу из основного потока.