Android: TimerTask запланирован для повторения, запускается только один раз - PullRequest
5 голосов
/ 11 июля 2011

Хорошо, это очень странная проблема, и я почти уверен, что я где-то напутал, но не могу понять, где.

Я пытаюсь -

  • Запланируйте Timer для выполнения TimerTask каждые пять секунд
  • TimerTask, в свою очередь, выполняет AsyncTask (который в этом случае просто спит секунду перед возвратом статического счетчика числа AsyncTasks).
  • Наконец, вышеупомянутый счетчик обновляется в пользовательском интерфейсе.

И, конечно же, соответствующие Handler s и Runnable s были использованы для отправки асинхронных сообщений из других потоков в пользовательский интерфейс.

Этот код выполняется только один раз. Я ожидаю, что это будет срабатывать каждые 5 секунд. Вот код

Примечание: Я понятия не имел, что делать с Looper. Я положил его туда после проб и ошибок!

public class TimerAsyncMixActivity extends Activity {
    public static final String TAG = "TimerAsyncMix";
    static int executionCount = 0;
    Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new Timer().schedule(new MyTimerTask(this), 0, 5000);
    }

    class MyAsyncTask extends AsyncTask<String, Void, Integer>{
        @Override
        protected Integer doInBackground(String... params) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return ++executionCount;
        }

        @Override
        protected void onPostExecute(Integer result) {

            mHandler.post(new UpdateUiThread(TimerAsyncMixActivity.this, result));
            super.onPostExecute(result);
        }
    }
}



class MyTimerTask extends TimerTask{
    private TimerAsyncMixActivity tma;

    public MyTimerTask(TimerAsyncMixActivity tma) {
        this.tma = tma;
    }

    @Override
    public void run() {
        Looper.prepare();
        Log.d(TimerAsyncMixActivity.TAG, "Timer task fired");
        tma.new MyAsyncTask().execute();
        Looper.loop();
        Looper.myLooper().quit();
    }
}

class UpdateUiThread implements Runnable{

    int displayCount;
    TimerAsyncMixActivity tma;
    public UpdateUiThread(TimerAsyncMixActivity tma, int i) {
        this.displayCount = i;
        this.tma = tma;
    }

    @Override
    public void run() {
        TextView tv = (TextView) tma.findViewById(R.id.tvDisplay);
        tv.setText("Execution count is : "+displayCount);
    }

Может кто-нибудь указать мне, что я делаю неправильно?

Ответы [ 2 ]

5 голосов
/ 12 июля 2011

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

У меня есть следующий код в моей деятельности. Когда я запускаю действие, я создаю асинхронную задачу и останавливаю ее на паузе. AsyncTask делает все, что ему нужно, и обновляет пользовательский интерфейс onProgressUpdate () (который выполняется в потоке пользовательского интерфейса, поэтому нет необходимости использовать обработчик).

private Task task;
@Override
protected void onPause() {
    task.stop();
    task = null;
}

@Override
protected void onResume() {
    task = new Task();
    task.execute();
}

private class Task extends AsyncTask<Void, String, Void> {

    private boolean running = true;
    @Override
    protected Void doInBackground(Void... params) {
        while( running ) {
            //fetch data from server;
            this.publishProgress("updated json");
            Thread.sleep(5000); // removed try/catch for readability
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        if( ! running ) {
            return; 
        }
        String json = values[0];
        //update views directly, as this is run on the UI thread. 
        //textView.setText(json);
    }

    public void stop() {
        running = false;
    }
}
1 голос
/ 12 июля 2011

Не используйте таймер.Если ваш телефон переходит в спящий режим, таймер тоже отключается.Используйте AlarmManager.

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