安卓的Handle

简介: 在安卓开发中,要求不能在主线程中做花费较长时间的UI操作,因为容易发生ANR(应用程序无响应(ANR:Application Not Responding):在一定的时间内没有做完相应的处理。)

在安卓开发中,要求不能在主线程中做花费较长时间的UI操作,因为容易发生ANR(应用程序无响应(ANR:Application Not Responding):在一定的时间内没有做完相应的处理。)

-   在Android中,应用程序的响应性是由Activity Manager和WindowManager系统服务进行监视 。如果响应输入的事件时间超过5S,broadcastReceiver超过10S,service超过20S,就会引起ANR。
-   用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。

避免ANR:1、不在主线程做耗时操作;2、不要让其他线程阻塞主线程的执行。

所以我们通常会把耗时操作移至子线程去操作,然后等子线程处理好耗时处理的事件,再通知UI进行变化,这时候就需要“Handle”(线程间通信)

Handler机制主要角色

Message: 消息,就是一个载体,包含消息ID,消息处理对象和处理的数据等,统一放到MessageQueue,最终由Handler处理。

Handler: 用于同一个进程的线程间通信,消息处理者,专门负责Message的发送和处理。我们使用Handler时,一般通过handleMessage(Message msg)来处理Message,也就是统一处理消息的回调,确保自己发出的消息也是自己来处理。

MessageQueue: 由名字可推出这是队列,就是存放Handler发送过来的消息,按照先进先出的顺序规则来执行。将链表的数据结构以Message来串联起来,等待Looper的抽取,为什么需要队列呢?因为同一线程在一个时间只能处理一个消息。因此需要队列来保存这些消息,然后挨个挨个拿出来处理,创建一个线程时并不会自动创建MessageQueue,但是主线程创建时会默认创建Looper对象,而Looper创建时就会创建MessageQueue,其他非主线程需要looper的时候就会通过调用prepare函数来实现。

Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列),首先,一个线程即是一段可执行的代码,作为App的主线程,不能让代码执行完,因为代码执行完的时候app就会自动退出,因此不能让主线程将代码段执行完,只能在代码中插入一个死循环,这时候Looper的作用就体现出来了,将主线程变成Looper线程。并且这时主线程就会在等其他线程发消息(更新UI和Activity状态等),另外,Looper会不断从消息队列取出消息送给主线程,也就是无限循环去查找是否有消息,有就去处理,没有的话就一直等待,一个MessageQueue需要一个Looper。

Thread: 负责调度整个消息的循环。

使用方法

通过handle与runnable中循环,使用sendMessage与post两个方法之间进行通讯。在runnable中运行耗时的操作,然后在handle中更新界面(UI). 1.创建handler,重写handleMessage()方法,在其内容中写要显示的界面 2.创建Runnable,在run中写费时间的代码,之后通过handle对象调用sendMessage()方法,发送消息到handle 3.如果要实现循环操作,就需要在handle中调用post()方法回到run中去。

使用步骤

1.创建Handler对象,重写handlerMessage(Message msg)方法,写出要显示的东西

Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            int index = msg.arg1;
            if(index == 100) {
               removeCallbacks(run);
            }
            progressBar.setProgress(index);
            handler.post(run);
        }
    };

2.创建runnable对象,实现run()方法,放入耗时操作

Runnable run = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count = count + 1;
            Message msg = handler.obtainMessage();
            msg.arg1 = count;
            handler.sendMessage(msg);
        }
    };
  1. 在主线程中调用:
handler.sendMessage(msg);

此外还要一些其他的方法也是差不多的机制去做耗时操作,以后再增加。

相关文章
|
XML Java API
安卓UI
安卓UI
|
移动开发 JavaScript Android开发
关于安卓jsbridge的使用
混合开发中,少不了的部分是JS与原生的交互,jsbridge为web端与原生交互提供了方便。
366 1
|
Android开发
|
XML 文件存储 Android开发
安卓 Activity 详解
常见容器视图示例: 类名称 description LinearLayout 在一行或一列里显示视图。 RelativeLayout 相对某个视图放置其他视图。 FrameLayout ViewGroup 包含一个子视图。 ScrollView 一种 FrameLayout,旨在让用户能够在视图中滚动查看内容。 ConstraintLayout 这是更新的 viewgroup;可以灵活地放置视图。在这节课的稍后阶段,我们将学习 ConstraintLayout。 Activity 会创建视图来向用户显示信息,并使用户与 Activity 互动。视图是 Android UI 框架中的类。它们占据
193 0
|
JavaScript 前端开发 Android开发
iOS中UIWebView的使用详解
iOS中UIWebView的使用详解
211 0
iOS中UIWebView的使用详解
|
iOS开发
iOS 开发之 NSURLSession
NSURLSession 所有的都在这里(一) NSURLSession 所有的都在这里(二)
1145 0
|
C# Android开发 iOS开发
xmarin live player 连接 IOS以及安卓实现实时效果查看
原文:xmarin live player 连接 IOS以及安卓实现实时效果查看 在之前有介绍过xamarin 单独IOS项目开发的运行环境搭建,但是这段时间我看到了xmarin forms 3.0  这东西竟然可以做都使用C#开发( IOS、Mac、安卓、UWP) APP应用,而且还是UI和逻辑都是共用一份。
1361 0
|
JavaScript Android开发 iOS开发
iOS UIWebView使用
1. 加载 WebView可直接加载.mp4,.pdf,.html,.doc等格式文件。 @interface ViewController () @property (nonatomic, strong) UIWebView *webView; @e...
1146 0
|
iOS开发
iOS NSURLSession DataTask(数据任务)
GET // get请求 - (void)get { NSURL *url = [NSURL URLWithString:@"http://127.
1115 0