• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Looper.prepare()和Looper.loop(),looper.prepare

Looper.prepare()和Looper.loop(),looper.prepare

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了looper.prepare,looper.loop,android looper.loop,loop.prepare,looper和marin等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Looper.prepare()和Looper.loop(),looper.prepare


 

什么时候需要 Looper

  Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,使用Looper.prepare()和Looper.loop()创建了消息队列就可以让消息处理在该线程中完成。

 

使用Looper需要注意什么

  写在Looper.loop()之后的代码不会被立即执行,当调用后mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。

比如下面的代码,只要调用了getLooper().quit()后代码2才会执行。

 1 class LooperThread extends Thread
 2 {
 3     4     public void run() 
 5     {
 6         Looper.prepare();
 7          //代码1....
 8         Looper.loop();
 9         //代码2....
10     }    
11 }        

 

警惕线程未终止造成的内存泄露;譬如在Activity中关联了一个生命周期超过Activity的Thread,在退出Activity时切记结束线程。一个典型的例子就是HandlerThread的run方法是一个死循环,它不会自己结束,线程的生命周期超过了Activity生命周期,我们必须手动在Activity的销毁方法中中调运thread.getLooper().quit();才不会泄露。

 

 

Looper与Activity

Activity的MainUI线程默认是有消息队列的。所以在Activity中新建Handler时,不需要先调用Looper.prepare()

 

主线程中的Looper.loop()一直无限循环为什么不会造成ANR

ActivityThread.java 是主线程入口的类,这里你可以看到写Java程序中司空见惯的main方法,而main方法正是整个Java程序的入口。

 

ActivityThread源码

1 public static final void main(String[] args) {
2         ...
3         //创建Looper和MessageQueue
4         Looper.prepareMainLooper();
5         ...
6         //轮询器开始轮询
7         Looper.loop();
8         ...
9     }

Looper.loop()方法

1  while (true) {
2        //取出消息队列的消息,可能会阻塞
3        Message msg = queue.next(); // might block
4        ...
5        //解析消息,分发消息
6        msg.target.dispatchMessage(msg);
7        ...
8     }

ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了。那为什么这个死循环不会造成ANR异常呢?

因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。也就说我们的代码其实就是在这个循环里面去执行的,当然不会阻塞了。


handleMessage方法部分源码

 1 public void handleMessage(Message msg) {
 2         if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
 3         switch (msg.what) {
 4             case LAUNCH_ACTIVITY: {
 5                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
 6                 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
 7                 r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
 8                 handleLaunchActivity(r, null);
 9                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
10             }
11             break;
12             case RELAUNCH_ACTIVITY: {
13                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
14                 ActivityClientRecord r = (ActivityClientRecord) msg.obj;
15                 handleRelaunchActivity(r);
16                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
17             }
18             break;
19             case PAUSE_ACTIVITY:
20                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
21                 handlePauseActivity((IBinder) msg.obj, false, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 2) != 0);
22                 maybeSnapshot();
23                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
24                 break;
25             case PAUSE_ACTIVITY_FINISHING:
26                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
27                 handlePauseActivity((IBinder) msg.obj, true, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 1) != 0);
28                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
29                 break;
30             ...........
31         }
32     }

可以看见Activity的生命周期都是依靠主线程的Looper.loop,当收到不同Message时则采用相应措施。

如果某个消息处理时间过长,比如你在onCreate(),onResume()里面处理耗时操作,那么下一次的消息比如用户的点击事件不能处理了,整个循环就会产生卡顿,时间一长就成了ANR。



引用:http://www.jianshu.com/p/cfe50b8b0a41  

 

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Looper.prepare()和Looper.loop(),looper.prepare

相关文章

  • 2017-05-26Android 自定义控件之第三讲:obtainStyledAttributes 系列函数详解
  • 2017-05-26Android studio 百度地图开发(2)地图定位
  • 2017-05-26msm8909+android5.1.1 由BLSP3改为BLSP1后SPI读写速度慢问题解决
  • 2017-05-26自定义控件——开关按钮ToggleButton,控件togglebutton
  • 2017-05-26android MediaPlayer 错误代码(error code)总结 转载,androidmediaplayer
  • 2017-05-26Android Support 包知识,androidsupport
  • 2017-05-26不带数据和返回的Activity跳转,返回activity跳转
  • 2017-05-26linux中fcntl()、lockf、flock的区别
  • 2017-05-26list集合的排序Comparator和Collections.sort,collections.sort排序
  • 2017-05-26关于jni编译32位、64位动态库(Android.mk和Application.mk文件),jniapplication.mk

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • android ImageSwitcher,imageswitcher
    • Hello,Android
    • 初探ListView,初探网
    • Android开发学习之路--网络编程之xml、json
    • arcgis andriod开发程序实例,有图有真相,arcgisandriod
    • 手机影音5--视频播放器的基本功能(2),5--基本功能
    • android中实现监听的四种方法,android四种方法
    • APP级别处理未捕获异常,APP级别处理捕获
    • AsyncTask.cancel()的结束问题,asynctaskcancel
    • Android开发:程序目录结构详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有