android线程之间的通信方式有哪些?
线程:是一个进程的实体,是CPU调度和分派的基本单位,是比进程更小的可以独立运行的基本单位。线程本身基本上没有系统资源,只有一些必不可少的资源(比如程序计数器,一组寄存器和堆栈),但是它可以和属于同一进程的其他线程共享进程拥有的所有资源。
差异:
(1),一个程序至少有一个进程,一个进程至少有一个线程;
(2)线程的划分规模小于进程的划分规模,使得多线程程序的并发性高;
(3)进程在执行时有独立的内存单元,多个线程* * *共享内存,但线程之间没有单独的地址空间。一个线程的死亡相当于整个进程的死亡。
-
首先,Android进程之间的通信模式
1.捆
由于活动、服务和接收者都可以通过意图携带捆绑传输数据,所以我们可以在一个流程中通过意图将捆绑携带数据发送给另一个流程的组件。
缺点:不能传输Bundle不支持的数据类型。
2.内容提供者
ContentProvider是Android的四大组件之一,以表单的形式存储数据并对外提供,即内容提供者可以跨进程访问其他应用中的数据。用法是继承ContentProvider,实现onCreate、query、update、insert、delete、getType的方法。oncreate在创建的时候负责做一些初始化工作,增加、删除、检查、修改的方法是查询、修改数据。getType返回一个指示Uri请求类型的字符串。注册后,可以使用ContentResolver请求指定的Uri。
3.证明文件
两个进程可以访问同一个文件来交换数据。我们不仅可以保存文本文件,还可以将对象保存到文件中,并从另一个文件中恢复它。应该注意,并发读/写时可能会出现并发问题。
4.广播
Broadcast可以向android系统中的所有应用发送广播,需要跨进程通信的应用可以监听这些广播。
5.AIDL模式
与内容提供商一样,服务也可以访问其他应用程序中数据。内容提供者返回一个光标对象,而服务返回一个Java对象。这种跨进程通信服务被称为AIDL服务。
AIDL定义了服务器的公开接口,并提供给客户端调用。AIDL使服务器能够并行处理,而Messenger只有封装AIDL后才能串行运行,所以Messenger一般用于消息传递。
6.送信人;通信员
信使是基于AIDL实现的。服务器(被动方)提供一个服务来处理客户端(主动方)的连接,维护一个处理程序来创建Messenger,并在onBind时返回Messenger的binder。
双方使用Messenger发送数据,使用Handler处理数据。Messenger依靠处理程序来处理数据,所以它是串行的。也就是说,当处理程序收到多个消息时,它会排队依次处理它们。
7.(电源)插座
Socket方法是通过网络交换数据,注意请求在子线程,否则会阻塞主线程。客户端和服务器在连接建立后可以持续传输数据,更适合实时数据传输。
二、Android线程间的通信方式
一般来说,线程间通信主要是指主线程(也叫UI线程)与子线程之间的通信。主要有两种方式:
1.异步任务机制
AsyncTask,异步任务,也就是说UI线程运行时,可以在后台执行一些异步操作;AsyncTask可以轻松正确地使用UI线程,它允许后台操作并将结果反馈给UI线程,而不显示工作线程或处理程序机制的使用。但是,AsyncTask只能用于短期操作(应该最多在几秒钟内结束的操作)。如果需要长时间在后台运行,则不适合使用AsyncTask,只能使用Java提供的其他API来实现。
2.处理器机制
Handler,继承自Object类,用于发送和处理消息对象或可运行对象;处理程序创建时会关联当前线程的Looper对象(如果当前线程的Looper为空或者不存在,会抛出异常,需要在线程中主动调用Looper.prepare()来创建Looper对象)。使用Handler的主要作用是在后面的进程中发送和处理message对象并让其他线程完成一个动作(比如通过worker线程中的Handler对象发送一个Message对象让UI线程更新UI,然后UI线程会得到MessageQueue中的Message对象(取出Message对象是由其关联的Looper对象完成的)并做出相应的响应。
第三,Android的两个子线程之间的通信
面试的时候可能会有面试官问到Android子线程之间的通信方式。因为大部分程序员主要关注Android主线程与子线程之间的通信,所以这个问题很容易被逼。
主线程与子线程之间的通信可以通过主线程中的处理程序将子线程中的消息发送给主线程中的looper,或者主线程中的处理程序通过post将runnable发送给looper。但是looper默认存在于主线程中,子线程中没有Looper。我该怎么办?其实原理很简单,把looper绑定到子线程,创建一个处理程序。通过在另一个线程中通过这个处理程序发送消息,可以实现子线程之间的通信。
子线程创建处理程序有两种方式:
方法1:为子线程创建一个Looper对象:
新线程(新Runnable() {
公共无效运行(){
looper . prepare();//为此线程创建一个Looper对象。一个Thead只有一个Looper对象。
Handler handler = new Handler(){
@覆盖
公共void handleMessage(Message msg) {
Toast . make text(getApplicationContext()," handleMessage ",Toast。长度_长)。show();
}
};
handler . senemptymessage(1);
looper . loop();//不断遍历MessageQueue中是否有消息。
};
}).start();
-
方法二:获取主线程的looper,或者UI线程的looper:
新线程(新Runnable() {
公共无效运行(){
handler handler = new handler(looper . getmainlooper()){//区别就在这里!!!
@覆盖
公共void handleMessage(Message msg) {
Toast . make text(getApplicationContext()," handleMessage ",Toast。长度_长)。show();
}
};
handler . senemptymessage(1);
};
}).start();