进程是一个具有独立功能的程序,用于分配和调度某个数据集上的执行活动,是系统分配和调度资源的独立单元。
线程:是进程的实体,是CPU调度和分配的基本单元,是小于进程且可以独立运行的基本单元。 线程本身基本上没有系统资源,只有程序计数器、寄存器、堆栈等执行所需的资源,但可以与属于同一进程的其他线程共享该进程的所有资源。
区别:
) 1、程序至少有一个进程,进程至少有一个线程;
) 2、由于线程分隔符尺度小于进程,多线程程序并发性高;
) 3、进程在运行中有独立的存储器单元,多个线程共享存储器,但线程之间没有独立的地址空间,一个线程死了整个进程就死了。
-----------------
一、安卓进程间通信方式
1.Bundle
Activity、Service和Receiver都是可以通过Intent携带绑定来传输数据的组件,因此可以通过Intent将携带数据的绑定发送到另一个进程。
缺点:无法传输Bundle不支持的数据类型。
2 .内容提供商
ContentProvider是Android的四个主要组件之一,用于以表格格式存储和向外提供数据。 这意味着ContentProvider可以在进程之间访问其他APP应用程序中的数据。 用法继承了ContentProvider,实现了onCreate、query、update、insert、delete和getType方法,onCreate是在创建时进行一些初始化的工作,添加/删除/更改的方法是在数据中进行初始化
3 .文件
这两个过程可以在同一个文件中交换数据,不仅可以保存文本文件,还可以将对象持久化为文件并从另一个文件中恢复。 请注意,同时读取/写入可能会同时发生。
4.Broadcast
Broadcast可以向android系统中的所有APP应用程序发送广播,需要进程间通信的APP应用程序可以接收这些广播。
5.AIDL方式
服务与Content Provider类似,可以访问其他APP应用程序中的数据。 Content Provider返回Cursor对象,Service返回Java对象。 能够进行这种进程间通信的服务称为AIDL服务。
AIDL通过定义服务端公开的接口并提供给客户端来调用。 Messenger通常用作消息传递,因为AIDL允许服务器并行处理,但Messenger只能在封装AIDL之后串行运行。
6 .消息传感器
Messenger基于AIDL实现,服务端(被动端)提供处理客户端(主动端)连接的服务,维护处置器创建Messenger,并在绑定时绑定消息
双方用Messenger发送数据,用Handler处理数据。 Messenger处理的数据依赖于处理程序,因此是串行的。 也就是说,如果处理程序收到多个消息,则按顺序排列处理。
7 .插座
请注意,套接字方法通过网络交换数据,并从子线程中请求。 否则,主线程将被阻止。 在客户端与服务端建立连接后,可以持续传输数据,适用于实时数据传输
二.安卓线程间通信方式
一般而言,线程间通信主要是指主线程(也称为UI线程)与子线程之间的通信,主要有以下两种方式:
1 .同步任务机制
在async任务、异步任务(即UI线程)运行时,可以在后台执行异步操作。async任务可以方便准确地使用UI线程。 AsyncTask允许后台操作,并将结果反馈到UI线程,而不指示使用工作线程或处理程序机制。 但是,async任务只能用于短时间操作(最大值秒内应该结束的操作),如果需要在后台长时间运行,则不适合使用async任务,只能使用Java提供的其他API来实现。
2 .处理程序机制
处理程序。 从object类继承,用于发送和处理消息对象或Runnable对象。 Handler在创建时与当前线程的Looper对象相关联。 如果当前线程的Looper为空或不存在,则抛出异常,需要在线程中主动调用Looper.prepare ()来创建Looper对象)。 使用Handler的主要角色是在后续进程中发送和处理消息对象,并让其他线程执行操作。 例如,如果在工作线程中通过Handler对象发送消息对象,然后让UI线程更新UI,则UI线程将在消息队列中检索该消息对象(例如
三.安卓两个子线程之间的通信
面试中,一些面试官
可能会问Android子线程之间的通信方式,由于绝大部分程序员主要关注的是Android主线程和子线程之间的通信,所以这个问题很容易让人懵逼。主线程和子线程之间的通信可以通过主线程中的handler把子线程中的message发给主线程中的looper,或者,主线程中的handler通过post向looper中发送一个runnable。但looper默认存在于main线程中,子线程中没有Looper,该怎么办呢?其实原理很简单,把looper绑定到子线程中,并且创建一个handler。在另一个线程中通过这个handler发送消息,就可以实现子线程之间的通信了。
子线程创建handler的两种方式:
方式一:给子线程创建Looper对象:
new Thread(new Runnable() {
public void run() {
Looper.prepare(); // 给这个Thread创建Looper对象,一个Thead只有一个Looper对象
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();
}
};
handler.sendEmptyMessage(1);
Looper.loop(); // 不断遍历MessageQueue中是否有消息
};
}).start();
---------------------
方式二:获取主线程的looper,或者说是UI线程的looper:
new Thread(new Runnable() {
public void run() {
Handler handler = new Handler(Looper.getMainLooper()){ // 区别在这!!!
@Override
public void handleMessage(Message msg) {
Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();
}
};
handler.sendEmptyMessage(1);
};
}).start();
---------------------