1, 进程和线程

通俗的讲, 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。

1,进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。

2,线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制的产生,并且线程的创建和销毁都会有相应的开销,当系统中存在大量的线程时,系统会通过时间陪轮转的方式调度每个线程,在这么多线程中有一个被称为主线程,主线程是指进程所拥有的线程。

2, Android中的线程

Android的线程也分为主线程和子线程,其中主线程又叫UI线程。在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity、BroadcastReceiver、Service)都会在同一个进程(Process)里执行,且由此进程的主线程负责执行。如果有特别指定(通过android:process),也可以让特定组件在不同的进程中运行。无论组件在哪一个进程中运行,默认情况下,他们都由此进程的主线程负责执行。

子线程

主线程主要处理界面交互相关的逻辑,主要是处理Activity组件的UI事件,Service后台服务工作。因为用户随时会和界面发生交互,因此主线程在任何时候都必须有比较高的响应速度,否则就会产生一种界面卡顿的感觉。

为了保持较高的响应速度,这就要求主线程中不能执行耗时的任务,这个时候子线程就派上用场了, 除了主线程以外的线程都是子线程。子线程主要是是执行耗时任务,比如网络请求,I/O操作等。

Android apk至少有三个线程,

1,ActivityThread创建的ApplicationThread(AMS远程调用)

2,activity 创建 ViewRoot.W

3,UI主线程

再说一次,

自定义Thread和UI线程的区别在于,UI线程是从ActivityThread运行的,在该类中的main()方法中,已经使用Looper.prepareMainLooper()为该线程添加了Looper对象,即已经为该线程创建了消息队列(MessageQueue),因此,程序员才可以在Activity中定义Hander对象(因为声明Hander对象时,所在的线程必须已经创建了MessageQueue)。而普通的自定义Thread是一个裸线程,因此,不能直接在Thread中定义Hander对象,从使用场景的角度讲,即不能直接给Thread对象发消息,但却可以给UI线程发消息。

3,ANR

Android希望UI线程能根据用户的要求做出快速响应,如果UI线程花太多时间处理后台的工作,当UI事件发生时,让用户等待时间超过5秒而未处理,Android系统就会给用户显示ANR提示信息。主线程除了处理UI事件之外,还要处理Broadcast消息。所以在BroadcastReceiver的onReceive()函数中,不宜占用太长的时间,否则导致主线程无法处理其它的Broadcast消息或UI事件。如果占用时间超过10秒, Android系统就会给用户显示ANR提示信息。解决办法自然还是解放UI主线程,将耗时操作交给子线程,避免阻塞。

4, 子线程与主线程通信

因为UI访问是没有加锁的,在多个线程中访问UI是不安全的,如果有多个子线程都去更新UI,会导致界面不断改变而混乱不堪。所以最好的解决办法就是只有一个线程有更新UI的权限,所以最合适的人选只能是主线程。

1,handler

2,AsyncTask

3,Activity.runOnUIThread(Runnable)

4,View.Post(Runnable)和View.PostDelayed(Runnabe,long)

其实后面三种方法也是对handler的一个包装,前面2中方法就不多说了,平常也用的最多。

4.1 runOnUIThread

应用举例,在子线程中,

runOnUiThread(new Runnable() {public void run() {•••}});

Acitivty中的runOnUiThread方法如下,

public final void runOnUiThread(Runnable action) {if (Thread.currentThread() != mUiThread) {mHandler.post(action);// 如果当前线程是子线程} else {action.run(); // 当前线程为主线程}}

runOnUiThread方法原理很简单了,也是通过handler方法来实现。

4.2 Post

View 的Post方法如下,

public boolean post(Runnable action) {final AttachInfo attachInfo = mAttachInfo;if (attachInfo != null) {return attachInfo.mHandler.post(action);}// Assume that post will succeed laterViewRootImpl.getRunQueue().post(action);return true;}

View 的postDelayed方法如下,

public boolean postDelayed(Runnable action, long delayMillis) {final AttachInfo attachInfo = mAttachInfo;if (attachInfo != null) {return attachInfo.mHandler.postDelayed(action, delayMillis);}// Assume that post will succeed laterViewRootImpl.getRunQueue().postDelayed(action, delayMillis);return true;}

5,小结

这几种方法各有优点。但是究其根本,其实后面几种方法都是对handler方法的包装,都是将message发送到UI线程的消息队列进行处理。

子线程与主线程之间的通信相关推荐

  1. handler回调主线程_Android使用Handler实现子线程与子线程、子线程与主线程之间通信...

    转载:https://blog.csdn.net/shaoenxiao/article/details/54561753 今天这篇文章只讲一下怎么使用Handler实现子线程与子线程之间.子线程与主线 ...

  2. Java学习笔记45:Java 线程与主线程之间的变量关系

    运行下面的代码: package com.test.www;public class Test {public static int count = 0;public static void inc( ...

  3. Python 多个线程按先后顺序执行,并保持各子线程和主线程的通信

    Python 多个线程按先后顺序执行,并保持各子线程和主线程的通信 摘要 最近有个项目使用pyqt5写的界面,界面展示部分作为项目的主线程,另外通过调用Thread,传入不同的参数又设置了五个子线程, ...

  4. Qt自定义事件实现及子线程向主线程传送事件消息

    近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就 ...

  5. android Handler Message传递参数,handler子线程和主线程通讯

    创建Handler private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) { ...

  6. python协程和线程_线程和协程之间的区别

    线程和协程之间的区别很大,甚至大过进程和线程之间的区别.线程建立在进程之上,协程建立在线程之上.那么协程是什么呢? 协程是一段计算机程序,它一般是一个协作类型的子程序,执行时允许暂停和恢复.协程非常适 ...

  7. Unity子线程与主线程交互(委托方式)

    Unity  Api无法从子线程访问, 但有些操作(例:IO存取文件)又必须子线程运行, 故实现在子线程做耗时操作, 完成后通知主线程更新状态 事件监听方式, 规避回调地狱:https://blog. ...

  8. Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息...

    先看简单示例:点击按钮,2s之后,TextView改变内容. package cn.lixyz.handlertest;import android.app.Activity; import andr ...

  9. QT子线程与主线程的信号槽通信

    最近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号 ...

  10. 【EventBus】事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )

    文章目录 前言 一.根据不同的线程模式进行不同的线程切换操作 二.完整代码示例 前言 发布线程发布事件之后 , 消息中心需要转发这些事件 , 并执行相应的订阅方法 ; 在转发的过程中 , 需要针对订阅 ...

最新文章

  1. .NET Core 2.1中改进的堆栈信息
  2. .whl文件打开方式 Python
  3. delve应该安装到哪_消防水炮安装高度为多少米标准
  4. 【Source Insight 】之marco学习笔记2
  5. 终于有了自己的域名了
  6. SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息
  7. BOS v2.0后台管理系统界面通用解决方案
  8. Algorithms-3.2 Binary Search Trees 二叉查找树
  9. 安全架构--2--关于企业安全体系建设历程的思考
  10. maven下载Nexus私服jar包,报错Not authorized
  11. 计算机网络工程这专业都学什么,网络工程专业学什么
  12. Arcmap技巧总结(豆丁)
  13. HCIP-DATACOM H12-831(41-60)
  14. 使用sqlhelper类查询时假如不需要参数化,那到时SqlParameter这个传参怎么处理
  15. Java 引用变量和实体变量
  16. 学习MATLAB的第一天,梳理一些见到的函数。1.matlab中sin、cos、tan三角函数问题。2.abs函数。3.vpa函数。4.disp函数。5.class函数。6.logical函数。
  17. linux stat函数讲解 -(转自秋水Leo)
  18. Python游戏开发,Python实现开心消消乐小游戏 附带源码
  19. 关于两个电源串并联的问题
  20. 基于Springboot+Vue实现智能停车场管理系统

热门文章

  1. C++笔记——第一个MFC程序
  2. Python3爬取西刺代理前2页国内高匿代理IP并验证有效性,若获取失败,使用快代理获取IP存入表格中
  3. MiniGUI源码分析——GDI概览及Surface
  4. Android双卡切换监测移动数据状态
  5. 大数据论文_01_GFS(个人总结)
  6. uis向3d投影全息界面的连续演化。
  7. oracle实现aes解密_AES加解密程序的实现
  8. 小小明_小小明手游框架_xxm_小小明手游平台
  9. java -jar -xx_java 启动方式 java -jar xx.jar
  10. 滴滴裁员 多一个月补偿反转苦情戏