zoukankan      html  css  js  c++  java
  • android学习笔记----定时问题

    两种方法:

    第一种:

    // 5000ms后执行run方法
    // 可以在这run()里面更新ui
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            tv.setText("呵呵呵呵呵");
            Log.d(TAG, "5s后我执行了");
        }
    }, 5000);

    上面效果就是5s后将TextView控件内容改为“呵呵呵呵呵”

    第二种:

    timer = new Timer();
    // 不能在这run()里面更新ui,除非使用runOnUiThread方法
    timerTask = new TimerTask() {
        @Override
        public void run() {
            tv.setText("哈哈哈哈哈");
            Log.d(TAG, "任务执行");
        }
    };
    timer.schedule(timerTask, 2000, 2000);

    timer.schedule的第三个参数是间隔多久重复一次,可以不设置,做一次性的任务。

    如果设置第三个参数就要记得在OnDestroy取消,不然activity销毁后定时任务仍然存在。

    如果在这里的run方法更新ui就需要使用runOnUiThread()方法。

    下面效果是每隔2s将TextView控件内容设置为“哈哈哈哈哈”

    timer = new Timer();
    // 不能在这run()里面更新ui,除非使用runOnUiThread方法
    timerTask = new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv.setText("哈哈哈哈哈");
                }
            });
            Log.d(TAG, "任务执行");
        }
    };
    timer.schedule(timerTask, 2000, 2000);

    否则抛异常android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its view

    Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作UI等,Android会直接异常退出,并提示should run on UIThread之类的错误日志信息。而对于隐式的非法操作,App不会直接简单粗暴地异常退出,只是出现奇怪的结果,Only the original thread that created a view hierarchy can touch its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。s.说明在错误的线程更新UI。

    总结点:

    不能在主线程(UI线程)进行耗时的操作,比如连接网络,拷贝大数据,睡眠等操作。

    比如连接谷歌网络。warning:java.net.SocketTimeoutException: connect timed out

    只要主线程超时 info:The application may be doing too much work on its main thread.

    在4.0之后谷歌强制要求连接网络不能在主线程进行访问

    只有主线程(UI线程)才可以更新UI

    定时代码如下

    MainActivity .java

    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.widget.TextView;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class MainActivity extends AppCompatActivity {
        final String TAG = "MainActivity";
        private Timer timer;
        private TimerTask timerTask;
        private TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv = (TextView) findViewById(R.id.tv);
            // 5000ms后执行run方法
            // 可以在这run()里面更新ui
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    tv.setText("呵呵呵呵呵");
                    Log.d(TAG, "5s后我执行了");
                }
            }, 5000);
            /*timer = new Timer();
            // 不能在这run()里面更新ui,除非使用runOnUiThread方法
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tv.setText("哈哈哈哈哈");
                        }
                    });
                    Log.d(TAG, "任务执行");
                }
            };
            timer.schedule(timerTask, 2000, 2000);*/
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            // 终止此计时器,丢弃任何当前计划的任务。 不干扰当前执行的任务(如果存在)。
            // 比如说定时器重复10个任务,cancel调用,我正在执行的任务就是最后一个任务,剩下的9个任务我不做了。
            //  一旦计时器被终止,它的执行线程就会顺利地终止,并且不会再安排任务了。
            timer.cancel();// 如果是第二种定时方法需要取消定时器
    
            // 如果此方法发生时任务正在运行,则任务将运行到完成,但不会再运行。
            // 也就是重复任务取消,最后任务表中的所有任务你就善始善终做完吧,可能还需要做几个任务这一轮才结束
            // 从重复定时器任务的run方法中调用此方法绝对保证计时器任务不会再次运行。
            // timerTask.cancel();
            Log.d(TAG, "onDestroy: ");
        }
    }

    =================================Talk is cheap, show me the code===============================

    CSDN博客地址:https://blog.csdn.net/qq_34115899
  • 相关阅读:
    使用BitMap进行海量数据去重
    记一次std::process::Child使用过程中碰到的问题
    我的第一篇rust博客
    优秀编程习惯总结
    利用generator模拟协程完美解决异步回调问题
    polymer框架在代码中动态创建需要支持内容分发的自定义元素并挂载到文档中
    属于自己的完美web服务器完成
    web components折腾记
    内边距的妙用
    用js修改带!important的css样式
  • 原文地址:https://www.cnblogs.com/lcy0515/p/10807885.html
Copyright © 2011-2022 走看看