zoukankan      html  css  js  c++  java
  • android Handler vs Timer

    Handler vs Timer

    在我们Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler。然而个人认为: Handler 在多个方面比Timer更为优秀,更推荐使用。

    一.易用性

    可重复执行 Handler可以重复执行某个任务。 Timer若在某个任务执行/取消之后,再次执行则会抛出一个IllegalStateException异常。为了避免这个异常,需要重新创建一个Timer对象。

    周期可调整

    若想要执行一个越来越快的定时任务,Handler可以做到,而Timer则消耗较大。 Handler

    • private Handler handler = new Handler();
      int mDelayTime = 1000;
      private Runnable runnable = new Runnable() {
        public void run() {
          update();
          if (mDelayTime > 0) {
            handler.postDelayed(this,mDelayTime); 
            mDelayTime -= 100;
          }
        }
      };
      handler.postDelayed(runnable,1000);

    如以上例子,就可以实现对周期的动态调整。 Timer的scheduleAtFixedRate(TimerTask task, long delay, long period)只能执行固定周期的任务,所以不可以动态地调整周期。若想

    要动态调整,则需要在执行玩一个定时器任务后,再启动一个新的任务时设置新的时间。

    UI界面更新 Handler:在创建的时候可以指定所在的线程,一般在Activity中构建的,即主线程上,所以可以在回调方法中很方便的更新

    界面。 Timer:异步回调,所以必须借助Handler去更新界面,不方便。  既然都得用Handler去更新界面了,为何不如把定时的功能也交

    Handler去做呢?

    二.内存占比

    Timer比Handler更占内存。接下来的Demo例子通过两种方法循环地打印日志,然后通过MAT插件来查看这两个类所需要调用的对象所产生的

    占比。

    int mCount = 0;
    private void startTimer() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
      @Override
      public void run() {
        Log.i("JKL", "" + mCount);
        mCount++;
        }
      }, 0, 200);
    }
    private void startHandler() {
    final Handler mHandler = new Handler();
    mHandler.post(new Runnable() {
      @Override
      public void run() {
        Log.i("JKL", "" + mCount);
        mCount++;
        mHandler.postDelayed(this, 200);
        }
      });
    }

     可以通过创建一个新的Android工程,在onCreate方法中调用以上startTimer或startHandler任意一个方法来测试。以下是MAT的测试结果。

    Timer相关对象的内存占比

     

    共有5个对象,占用1192B。Handler相关对象的内存占比

        我们可以看到上面有2个Handler,这时候你是否会疑惑呢?其实一个是我们生成的Handler,另外一个是Activity默认生成的,存在于ViewRootImp中,这涉及到ViewTree的知识,此处不便展开。

    不过我们可以知道,我们自己构建的Handler,最多也就只占64B。

     

    在使用Handler的时候,还需要用到Runnable,不过也只占了16B。所以,使用Handler的方式来作为定时器,最多也就是80B。

    以上可以得出结论,相比起Timer方式的定时器占用1192B,Handler的方式占用资源会小很多,只有1/60。

    所以Handler的方式比较节省内存。

    写到这里,想到一个点,Timer是创建一个线程去计数的,而Handler是在默认主线程运行的。假若Handler也用一个异步线程去运行,会不会耗很多资源呢?以下是测试代码:

    private void startHandler() {
      HandlerThread thread = new HandlerThread("Test");
      thread.start();
      final Handler mHandler = new Handler(thread.getLooper());
      mHandler.post(new Runnable() {
        @Override
        public void run() {
          Log.i("JKL", "" + mCount);
          mCount++;
          mHandler.postDelayed(this, 200);
          }
      });
    }

      

    以上用一个HandlerThread来启动一个新的线程。再看看内存占比

    以看到HandlerThread也只是占了96B的内存。

    综上所述,Handler内存占比低!而且低了不少。

    无论从易用性还是内存占比出发,Handler更胜一筹

  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/yujian-bcq/p/4691513.html
Copyright © 2011-2022 走看看