zoukankan      html  css  js  c++  java
  • Android_handler

    背景:

      1.主线程(UI线程):主要负责UI更新,为了提高性能,Android的UI线程是不安全的,子线程无法直接更新UI

      2.消息循环机制:UI线程是个死循环

    应用:1.定时任务

      2.线程与线程交互

    handler方法使用:

    简单使用:子线程通知UI更新

    public class MainActivity extends AppCompatActivity {
    
        protected Handler handler;
        protected TextView textView;
    
        @SuppressLint("HandlerLeak")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            /*
            UI线程
            */
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = findViewById(R.id.textView);
            handler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    //主线程接受到子线程发送的消息,更新数据
                    if(msg.what == 1001011){
                        textView.setText("消息");
                    }
                }
            };
    
            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //又可能做大量耗时操作如下载文件
                    new Thread(){
                        @Override
                        public void run() {
                            //子线程发送消息
                            handler.sendEmptyMessage(1001011);
                        }
                    }.start();
                }
            });
        }
    }

    如果在子线程中直接更新UI:

      则会提示异常信息:只有在主线程中才能更新view

    常用方法:

     //使用obtain实例化Message(建议),会做一个缓存
                            Message message = Message.obtain();
                            //标识,相当于密码箱的密码,int类型
                            message.what = 10010;
                            message.arg1 = 10011;
                            message.arg2 = 10012;
                            //对象,可以是上下文
                            message.obj = MainActivity.this;
                            //空消息
                            handler.sendEmptyMessage(1001013);
                            //约定一个时间发送,绝对时间 准时发送
                            handler.sendMessageAtTime(message,6000);
                            //相对时间  XX秒后发送
                            handler.sendMessageDelayed(message,2000);
                            //发送一个可执行程序,立即发出
                            Runnable runnable = new Runnable() {
                                @Override
                                public void run() {
                                    int a = 1 + 3;
                                }
                            };
                            handler.post(runnable);
                            //执行程序时使用run方法
                            runnable.run();
                            //定时任务
                            handler.postAtTime(runnable,2000);

    Demo:

    1.下载文件并更新进度条 

    public class DownActivity extends AppCompatActivity {
    
        public static final int INT = 1001011;
        protected ProgressBar progressBar;
        protected Handler handler;
    
        private static final String TAG = "DownActivity";
        protected int progress;
    
        @SuppressLint("HandlerLeak")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_down);
            findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    downData();
                }
            });
            progressBar = findViewById(R.id.progressBar);
            /**
             * UI线程接收消息
             */
            handler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    if (msg.what == INT){
                        Log.e(TAG, "handleMessage: "+ "判断成功" );
                        progress = (Integer) msg.obj;
                        //设置进度条进度
                        progressBar.setProgress(progress);
                    }
                }
            };
        }
    
        private void downData() {
            /**
             * 子线程,下载文件
             */
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        URL url = new URL("https://clfile.imooc.com/class/assist/119/4289211/Handler%E6%BA%90%E7%A0%81(%E4%BB%A3%E7%A0%81%E7%BB%8F%E8%BF%87%E5%B0%81%E8%A3%85).rar");
                        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                        InputStream inputStream = httpURLConnection.getInputStream();
                        //获取文件总长度
                        int filesize = httpURLConnection.getContentLength();
                        //下载文件夹名称
                        String downloadFolderName = Environment.getExternalStorageDirectory() + File.separator + "我的下载文件"  + File.separator;
                        File file = new File(downloadFolderName);
                        //如果文件夹不存在,则创建
                        if(!file.exists()){
                            file.mkdir();
                        }
                        //下载文件名
                        String filename = downloadFolderName + "源代码";
                        File file1 = new File(filename);
                        if(file1.exists()){
                            file1.delete();
                        }
                        //已下载文件长度
                        int downsize = 0;
                        int len = 0;
                        byte[] b = new byte[1024*10];
                        OutputStream outputStream= new FileOutputStream(filename);
                       while ((len = inputStream.read(b)) != -1){
                           outputStream.write(b,0,len);
                           downsize += len;
                           Message message = Message.obtain();
                           message.obj = downsize*100/filesize;
                           message.what = INT;
                            handler.sendMessage(message);
                        }
    
    
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
            }).start();
        }
    }

    下载网络图片,通过handle更新ImageView控件显示图片

    public class PicActivity extends AppCompatActivity {
        MyHandler2 myHandler2 = new MyHandler2(this);
        protected ImageView imageView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_pic);
            imageView = findViewById(R.id.imageView);
            findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    getPicture();
    
                }
            });
        }
    
        void getPicture(){
           new Thread(new Runnable() {
               @Override
               public void run() {
                   try {
                       URL url = new URL("https://img2.mukewang.com/5adfee7f0001cbb906000338-240-135.jpg");
                       HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                       httpURLConnection.setRequestMethod("GET");
                       httpURLConnection.setConnectTimeout(5000);
                       if (httpURLConnection.getResponseCode() ==200){
                           InputStream inputStream = httpURLConnection.getInputStream();
                           //获取流
                           Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                           Message message = Message.obtain();
                           message.what = 10010;
                           message.obj = bitmap;
                           //发送消息
                           myHandler2.sendMessage(message);
                       }
    
                   } catch (MalformedURLException e) {
                       e.printStackTrace();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
    
               }).start();
           }
    
        /**
         * 静态 弱引用 handle 避免发生内存泄漏
         * 当handle持有PicActivity的引用也能被回收
         */
        static class  MyHandler2 extends Handler{
            WeakReference<PicActivity> weakReference;
    
            private MyHandler2(PicActivity activity) {
                this.weakReference =new WeakReference<>(activity);
            }
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //获取当前activity
                PicActivity picActivity = weakReference.get();
                switch (msg.what){
                    case 10010:
                        Bitmap bitmap = (Bitmap) msg.obj;
                        picActivity.imageView.setImageBitmap(bitmap);
                }
            }
        }
    }

    通过handle更新显示内容,通过延迟发送sendMessageDelayed,实现倒计时功能

    public class TimeActivity extends AppCompatActivity {
    
        public static final int MAX = 10;
        public static final int CODE = 10010;
        protected TextView textView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_time);
            textView = findViewById(R.id.textView2);
            MyHandler myHandler = new MyHandler(this);
            Message message = Message.obtain();
            message.what = 10010;
            message.arg1 = MAX;
            myHandler.sendMessageDelayed(message, 1000);
    
        }
    
      public static class MyHandler extends Handler {
            WeakReference<TimeActivity> weakReference;
    
            private MyHandler(TimeActivity activity) {
                this.weakReference = new WeakReference<>(activity);
            }
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                int value = 0;
                TimeActivity timeActivity = weakReference.get();
                if (msg.what == 10010) {
                    value = msg.arg1;
                    timeActivity.textView.setText(String.valueOf(value--));
                }
                //实现消息循环发送,直至不满足条件
                if (value > 0) {
                    Message message = Message.obtain();
                    message.what = 10010;
                    message.arg1 = value;
                    sendMessageDelayed(message, 1000);
                }
            }
        }
    }
  • 相关阅读:
    单例模式——C++实现
    单例模式——java实现
    组合模式——java实现
    桥接模式——Java实现
    桥接模式——C++实现
    适配器模式——java实现
    编写一个显示当前时间的jsp页面
    适配器模式——C++实现
    安装配置hadoop1
    Nginx使用教程
  • 原文地址:https://www.cnblogs.com/conglingkaishi/p/9373972.html
Copyright © 2011-2022 走看看