Так я наконец-то достиг этого. Обратите внимание, что метод AsyncTask cancel (true) в моем сценарии бесполезен из-за рекурсии. Я использовал то, что предложил @CommonsWare - использовал флаг, чтобы указать, нужно ли выполнять еще какие-либо задачи.
ужно, чтобы мое приложение Android периодически получало данные с сервера с помощью вызовов AJAX и соответственно обновляло пользовательский интерфейс (всего несколькоTextView
s, которые должны быть обновлены сsetText()
). Обратите внимание, что это включает в себя 2 задачи:
AsyncTask
за это.Делать вышеуказанное многократно, через равные промежутки времени.Я не нашел элегантный способ достичь пункта 2 выше. В настоящее время я просто выполняю саму задачу изOnPostExecute()
, Я читаю наэта тема на SO что мне не нужно беспокоиться о сборке мусора, если речь идет об объектах AsyncTask.
Но я все еще не уверен, как настроить таймер, который будет запускать мою AsyncTask после того, как истечет время. Любые указатели будут оценены. Вот мой код:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AjaxRequestTask().execute(MY_REST_API_URL);
}
private void updateReadings(String newReadings) {
//Update the UI
}
class AjaxRequestTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... restApiUrl) {
//Do AJAX Request
}
@Override
protected void onPostExecute(String result) {
updateReadings(result);
/*Is there a more elegant way to achieve this than create a new AsyncTask object every 10 seconds? Also, How can I update the UI if I create a timer here? */
new AjaxRequestTask().execute(MY_REST_API_URL);
}
}
}
заранее спасибо
РЕДАКТИРОВАТЬ: Я пытался опубликовать ответ, но не смог сделать это, так как у меня нет репутации, чтобы ответить в течение 8 часов.
Ну вот и я нашел решение. Я не уверен, однако.
protected void onPostExecute(String result) {
updateReadings(result);
// super.onPostExecute(result);
new Timer().schedule(
new TimerTask() {
@Override
public void run() {
new AjaxRequestTask().execute(MY_REST_API_URL);
}
},
TIMER_ONE_TIME_EXECUTION_DELAY
);
}
Есть ли какие-то оборотные стороны, о которых я должен знать, когда использую это? В частности, я вижу много GC, происходящих в LogCat. Кроме того, мне интересно, какAsyncTask
может быть кандидатом в GC, если толькоonPostExecute()
завершается?
Как я могу "остановить" обновления? Один из способов, о котором я подумал, - сделать самый первыйAsyncTask
экземпляр как переменная-членActivity
, Таким образом, я могу призватьcancel(true)
на это и надеюсь, что это "остановит" задачи.
В случае, если кто-то ищет что-то подобное - ни одно из упомянутых здесь решений не работает удовлетворительно. Все они страдают отOutOfMemory
вопросы. Я не отлаживал детали OOM, но подозреваю, что это может быть связано либо с рекурсией, либо с наличием связанных с HTTP объектов в качестве переменных-членов вAsyncTask
а не как членыActivity
(в основном из-за НЕ повторного использования HTTP и других объектов).
Я отказался от этого подхода за другой - бесконечно совершая мои Ajax Calls вdoInBackground()
из моегоAsyncTask
; и обновление интерфейса вonProgressUpdate()
, Таким образом, я также избегаю затрат на поддержку слишком большого количества потоков илиHandler
s для обновления пользовательского интерфейса (помните, пользовательский интерфейс может быть обновлен вonProgressUpdate()
).
Этот подход также устраняет необходимостьTimer
с иTimerTask
с, в пользу использованияThread.sleep()
вместо.Эта тема на ТА имеет больше деталей и фрагмент кода тоже.