美文网首页
android定时器的使用

android定时器的使用

作者: 努力深耕Android的小透明 | 来源:发表于2018-03-26 15:10 被阅读504次

  目前在项目中使用过的定时器主要是两种方式:1.handler的延时任务 2.timer的定时器

  下面主要来介绍这两种方式 定时器的用法,和遇到的坑 :
  1.handler的延时任务
  写了一个demo,是关于hanlder发送延时消息和 取消延时消息的


image.png

package com.phicomm.android.test.demo;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mOpenButton;
    private Handler mHandler;
    private Runnable mRunnable;
    private Button mCloseButton;

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

    }

    private void initView() {
        mOpenButton = (Button) findViewById(R.id.btn_open);
        mCloseButton = (Button) findViewById(R.id.btn_close);
        mOpenButton.setOnClickListener(this);
        mCloseButton.setOnClickListener(this);
        mHandler = new Handler();

    }



    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_open:
                mRunnable = new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "1s后延时任务执行了"+mRunnable.toString(), Toast.LENGTH_SHORT).show();
                    }
                };
                mHandler.postDelayed(mRunnable,1000);
            break;
            case R.id.btn_close:
               mHandler.removeCallbacksAndMessages(mRunnable);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(mRunnable);
        }
    }
}


  但是在实际运用的过程中,常常会出现无法移除延时消息的问题,这个问题主要是因为两个runnable的对象不是同一个,
  当Activity进入后台运行后再转入前台运行,removeCallbacks无法将updateThread从message queue中移除。这是为什么呢?
  在Activity由前台转后台过程中,线程是一直在运行的,但是当Activity转入前台时会重新定义Runnable runnable;也就是说此时从message queue移除的runnable与原先加入message queue中的runnable并非是同一个对象。  解决方式1:如果把runnable定义为静态的则removeCallbacks不会失效,对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,我们做如下修改就能解决上面的这个问题.

  解决方式2:将所有的runnable任务放到一个集合中,根据runnable的id移除相应的任务,即可以解决这个问题

2.timer的延时任务
同样用上面的demo来说明使用方法:
要注意的是:
TimerTask运行在一个单独的线程里,而不是UI线程。所以使用Android timer时,注意android的单线程原则,确保线程安全。不要在TimerTask的run方法中做UI相关的操作,如:TextView.setText()等,这样可能会导致UI线程阻塞。如果需要可以使用handler向UI线程发消息,具体处理由UI线程自己完成。在使用完Timer之后,要使用Timer的cancel方法取消Timer,否则Timer一直在运行。

image.png
package com.phicomm.android.test.timer;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.phicomm.android.test.demo.R;

import java.util.Timer;
import java.util.TimerTask;

public class TimerActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mOpenButton;
    private Button mCloseButton;
    private Timer mTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timer);
        initView();
    }

    private void initView() {
        mOpenButton = (Button) findViewById(R.id.btn_open);
        mCloseButton = (Button) findViewById(R.id.btn_close);
        mOpenButton.setOnClickListener(this);
        mCloseButton.setOnClickListener(this);
        mTimer = new Timer();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_open:
                TimerTask timerTask = new TimerTask(){
                    @Override
                    public void run() {
                       runOnUiThread(new Runnable() {
                           @Override
                           public void run() {
                               Toast.makeText(TimerActivity.this, "1s后延时任务执行了", Toast.LENGTH_SHORT).show();
                           }
                       });
                    }
                };
                mTimer.schedule(timerTask,1000);
                break;
            case R.id.btn_close:
                mTimer.cancel();

                break;
        }
    }
}

  这里需要注意的是,timer的cancel方法只能执行一次,不能在调用了cancel之后再进行timer的任务执行。

参考文章:
Android 定时器实现的几种方式和removeCallbacks失效问题详解

Android 中Timer和TimeTask完成定时任务

相关文章

  • android定时器的使用

      目前在项目中使用过的定时器主要是两种方式:1.handler的延时任务 2.timer的定时器   下面主要来...

  • Timer 实现倒计时功能

    Android 定时器 在Android开发中有些任务是需要通过延时来完成的,这个时候就用到了定时器Timer

  • 无标题文章

    iOS NSTimer使用详解-开启、关闭、移除 定时器定时器详解ios定时器关闭定时器NSTimer 1、要使用...

  • VUE中定时器如何使用?

    定时器的创建和使用 定时器的销毁 定时器 setTimeout()方法 和 setInterval() 使用方法相...

  • Android 定时器Timer的使用

    定时器有什么用 在我们Android客户端上有时候可能有些任务不是当时就执行,而是过了一个规定的时间在执行此次任务...

  • AlarmManager 设置和取消定时器 实例

    使用 AlarmManager 设置定时器的方法如下: 使用 AlarmManager 取消定时器的方法如下: 下...

  • 初识js下的定时器

    定时器 setTimeout、setInterval 定时器的使用方法 setTimeout(fn,1000) ...

  • Vue @hook

    使用之前我们在Vue使用定时器的时候,在创建定时器的时候,当页面不存在的时候需要销毁定时器。我们一般会这样使用 但...

  • 如何在linux创建定时器 --- 2019-08-08

    在Linux使用定时器,其实就是任务调度的使用,依赖crontab,使用这种任务调度的定时器最重要的是要使用正确的...

  • 飞机大战

    # 敌机出场 ##目标 *使用**定时器**添加敌机 *设计`Enemy`类 ## 01. 使用定时器添加敌机 运...

网友评论

      本文标题:android定时器的使用

      本文链接:https://www.haomeiwen.com/subject/zyhvqftx.html