Android - 每 5 秒循环一次部分代码

Posted

技术标签:

【中文标题】Android - 每 5 秒循环一次部分代码【英文标题】:Android - loop part of the code every 5 seconds 【发布时间】:2014-02-12 11:02:28 【问题描述】:

当我按下按钮 START 并结束它时,我想每 5 秒开始重复两行代码,当我按下按钮 STOP 时。我正在尝试使用 TimerTask 和 Handles,但无法弄清楚如何。

public class MainActivity extends Activity 




    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


           //final int i;
           final TextView textView = (TextView) findViewById(R.id.textView);
           final Button START_STOP = (Button) findViewById(R.id.START_STOP);
           final ImageView random_note = (ImageView) findViewById(R.id.random_note);
           final int min = 0;
           final int max = 2;
           final Integer[] image =  R.drawable.a0, R.drawable.a1,R.drawable.a2 ;



        START_STOP.setTag(1);
        START_STOP.setText("START");


        START_STOP.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View v) 
            int status = (Integer) v.getTag();
            if (status ==1) 
                textView.setText("Hello");
                START_STOP.setText("STOP");
                v.setTag(0);

                final Random random = new Random();

                                //************************************************************
                // I would like to loop next 2 lines of code every 5 seconds.//

                                int i = random.nextInt(2 - 0 + 1) + 0;
                random_note.setImageResource(image[i]);

                //************************************************************
                    

            else
            
                textView.setText("Bye");
                START_STOP.setText("Let's PLAY!");
                v.setTag(1);
            


            
        );     

    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    



【问题讨论】:

TimerTask 有什么问题? 我不知道。当我试图在模拟器上运行它时,它崩溃了。但可能我做错了什么,因为我是 android (Java) 初学者。 【参考方案1】:

在其他答案之一中使用 CountDownTimer 是一种方法。另一种方法是使用 Handler 和 postDelayed 方法:

private boolean started = false;
private Handler handler = new Handler();

private Runnable runnable = new Runnable()         
    @Override
    public void run() 
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
        if(started) 
            start();
        
    
;

public void stop() 
    started = false;
    handler.removeCallbacks(runnable);


public void start() 
    started = true;
    handler.postDelayed(runnable, 2000);        

这是一个使用 Timer 和 TimerTask 的示例:

private Timer timer;
private TimerTask timerTask = new TimerTask() 

    @Override
    public void run() 
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
    
;

public void start() 
    if(timer != null) 
        return;
    
    timer = new Timer();
    timer.scheduleAtFixedRate(timerTask, 0, 2000);


public void stop() 
    timer.cancel();
    timer = null;

【讨论】:

我一直在我的应用程序中使用 CountDownTimer,例如每 5 秒更改一次活动中的横幅。每 5 秒重复一次操作的最佳方式是什么,CountDownTimer 或 Handler 和 postDelayed? 谢谢。你会把它放在我的原始代码中的什么地方? 好问题 giacomoni!我看了一下 CountDownTimer ,它在内部使用了一个处理程序:grepcode.com/file/repository.grepcode.com/java/ext/… 所以我猜它们或多或少是等价的。 Timer 使用带有 TimerTasks 队列的 TimerThread:grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/… 很难说哪个更好。我不太了解线程和处理程序之间的区别,无法给您足够好的答案。 @Damijan 将 start 和 stop 方法放在您的活动中的某个位置。根据按钮状态从 onClick() 方法调用它们。将 TimerTask 或 Runnable 放入您的 Activity 以及 Activity 的普通成员变量中【参考方案2】:

您可以使用CountDownTimer作为以下方法:

private CountDownTimer timer;

timer = new CountDownTimer(5000, 20) 

    @Override
    public void onTick(long millisUntilFinished) 

    

    @Override
    public void onFinish() 
        try
            yourMethod();
        catch(Exception e)
            Log.e("Error", "Error: " + e.toString());
        
    
.start();

然后再次调用计时器:

public void yourMethod()
    //do what you want
    timer.start();

取消定时器可以拨打timer.cancel();

希望对你有帮助!

【讨论】:

你好先生,上面的代码可以用来刷新一个活动,直到用户点击返回按钮......?【参考方案3】:

您可以使用 RxJava2/RxAndroid2 并创建一个每秒发出一条消息(或任何您想要的消息)的 Observable,例如使用伪代码:

Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS)
            .timeInterval()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Timed<Long>>() 
                @Override
                public void accept(@NonNull Timed<Long> longTimed) throws Exception                
                    //your code here.
                    Log.d(TAG, new DateTime());
                
            );

当你想停止它时,你可以简单地调用:

timer.dispose();

我发现此代码比其他选项更具可读性。

【讨论】:

【参考方案4】:

除了提到使用 Handler、CountDownTimer 和常规 Timer 之间的区别之外,我没有更多要补充的。正如 britzl 所提到的,CountDownTimer 在内部使用了一个 Handler,所以这相当于直接使用这个 handler。处理程序用于在很短的时间内运行 Ui 的东西。一个例子是文本视图的 setText。对于计算密集型任务,处理程序可能会导致延迟。计时器也只能运行短任务,但不一定只用于 UI 内容。对于更复杂的任务,应该使用新的线程。

【讨论】:

以上是关于Android - 每 5 秒循环一次部分代码的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何通过服务每 5 秒发送一次 http 请求

C# 要想给一个死循环设置循环时间间隔,每5秒循环一次。

如何每 20 秒执行一次 bash 脚本? ,好用睡眠和循环?

python循环控制间隔。

js循环倒计时代码 每5秒循环倒计时到0 再从5秒开始 到0之后刷新页面 类似网易的滚动新闻

如何制作一个循环或每 5 秒执行一次任务然后自行重置的东西?