Android:安排重复的 TimerTask 仅被触发一次

发布于 2024-11-19 08:42:57 字数 2304 浏览 2 评论 0原文

好吧,这是我遇到的一个非常奇怪的问题,我很确定我在某个地方搞砸了,但我不太清楚在哪里。

我正在尝试的是 -

  • 安排一个 Timer 每五秒执行一个 TimerTask
  • TimerTask 依次执行一个 AsyncTask > (在本例中,它简单地休眠一秒钟,然后返回 AsyncTasks 数量的静态计数)。
  • 最后,上述计数在 UI 中更新。

当然,适当的 Handler 和 Runnable 已用于将异步消息从其他线程发布到 UI。

该代码仅执行一次。我预计它每 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);
    }

谁能指出我做错了什么?

Ok this is a very weird problem I am having, and I'm pretty sure that I am messing up somewhere, but I can't quite figure out where.

What I am trying is -

  • Schedule a Timer to execute a TimerTask every five seconds
  • The TimerTask in turn executes an AsyncTask (which in this case simple sleeps for a second before returning the static count of the number of AsyncTasks).
  • Finally, the aforementioned count is updated in the UI.

And of course, the appropriate Handlers and Runnables have been used to post asynchronous messages from other threads to the UI.

This code executes only once. I expect it to fire every 5 seconds. Here's the code.

Note: I had no idea what to do with the Looper. I put it there after trial and error!

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);
    }

Can anyone point me to what I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一桥轻雨一伞开 2024-11-26 08:42:57

技术人员,这就是我实现类似事情的方式。我不会说这是最好的方法,但它对我有用,而且看起来还不错。

我的活动中有以下代码。我在活动开始时创建一个异步任务,并在暂停时停止它。 AsyncTask 会做它需要做的任何事情,并在 onProgressUpdate() 上更新 UI(它在 UI 线程上运行,因此不需要使用 Handler)。

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;
    }
}

techie, this is how I implemented similar things. I'm won't claim that this is the best way, but it has worked for me and doesn't look too bad.

I have the following code in my activity. I create an async task when the activity starts and I stop it onPause. The AsyncTask does whatever it needs to do, and updates the UI on onProgressUpdate() (which is run on the UI thread, so there's no need to use a Handler).

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;
    }
}
烛影斜 2024-11-26 08:42:57

不要使用计时器。如果您的手机进入睡眠状态,计时器也会暂停。使用警报管理器。

Do not use a timer. If your phone goes to sleep, the timer is suspended too. Use AlarmManager.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文