• 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
  • 相关阅读:
    浅析Vue Router中关于路由守卫的应用以及在全局导航守卫中检查元字段
    react-native 项目配置ts运行环境
    #mobx应用在rn项目中
    react-native TextInput输入框输入时关键字高亮
    react-native-亲测可用插件
    nodejs+express实现图片上传
    cordova图片上传,视频上传(上传多个图片,多个视频)
    cordova图片上传,视频上传(上传单个图片,单个视频)
    移动端如何测试(前端,cordova)
    在mac上将apk包安装到android手机上
  • 原文地址:https://www.cnblogs.com/lcy0515/p/10807885.html
Copyright © 2020-2023  润新知