当前位置:首页 » 安卓系统 » 安卓线程之间通讯用什么对象

安卓线程之间通讯用什么对象

发布时间: 2022-04-22 06:10:56

① 面试被问到android中两个子线程怎么通信,我懵了。

构造HandlerThread类的对象mHandlerThread,这样生成一个子线程可以调用new MyHandler(mHandlerThread.getLooper())来获取子线程的handler,另一个子线程发消息,收到消息的就是子线程而不是主线程了。

② 线程间通信有哪些方式

线程间通信方式有:

1、volatile

volatile有两大特性,一是可见性,二是有序性,禁止指令重排序,其中可见性就是可以让线程之间进行通信。volatile语义保证线程可见性有两个原则保证:

(1)所有volatile修饰的变量一旦被某个线程更改,必须立即刷新到主内存。

(2)所有volatile修饰的变量在使用之前必须重新读取主内存的值。

2、等待/通知机制

等待通知机制是基于wait和notify方法来实现的,在一个线程内调用该线程锁对象的wait方法,线程将进入等待队列进行等待直到被通知或者被唤醒。

3、join方式

join其实合理理解成是线程合并,当在一个线程调用另一个线程的join方法时,当前线程阻塞等待被调用join方法的线程执行完毕才能继续执行,所以join的好处能够保证线程的执行顺序。

但是如果调用线程的join方法其实已经失去了并行的意义,虽然存在多个线程,但是本质上还是串行的,最后join的实现其实是基于等待通知机制的。

4、threadLocal

threadLocal方式的线程通信,不像以上三种方式是多个线程之间的通信,它更像是一个线程内部的通信,将当前线程和一个map绑定,在当前线程内可以任意存取数据,减省了方法调用间参数的传递。

线程特点:

1、轻型实体

线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源。线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述。

2、独立调度和分派的基本单位

在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(在同一进程中的)。

3、可并发执行

在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

4、共享进程资源

在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址。

此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。

③ 安卓多线程间通信和多进程之间通信有什么不同

1)共享变量(内存)
2)管道
3)handle机制
runOnUiThread(Runnable)
view.post(Runnable)
android 进程内的消息驱动机制---Handler,MessageQueue,Runnable,Looper
Looper和Message的处理机制:首先在主线程中创建了一个handler对象,目的是为了处理从子线程发送过来的消息,然后当子线程有发送消息的需求时会使用Message对象,消息首先会被存储在Message queue消息队列中,主线程还有一个Looper消息轮询器,会循环遍历消息队列中的消息,当发现消息的时候会发送消息给handler处理(更新ui等操作),handler调用handleMessage处理完后将Message置为null以便回收.

④ android中什么时候会选择用广播来进行线程间的通信

android中什么时候会选择用广播来进行线程间的通信 Android 多线程 通信

线程中通信就不要用广播了吧 进程中通信可以用广播或者aidl

可是,这两天看到的项目都是这么做的;然后,自己分析了下,觉得一下的理由也是可以成立的;

1.正常情况下我们选择handler消息机制来进行单向的线程间的通信;(工作线程向主线程发送消息)

因为主线程有现成的handler,而工作线程没有现成的handler,这样的话,主线程将handler交给工作线程而让工作线程将工作的结果交给主线程;

相反,工作线程中没有现成的handler(事实上是没有消息队列,也就是handler没有绑定到工作线程),那么,如果开辟的话,代码角度上是挺麻烦的(相对应广播机制来说);

2.广播机制本身就是双向的(工作线程向主线程发送广播,主线程向工作线程发送广播);

//另外,对于像一个activity中通过fragment来进行界面的处理; 我们大多数情况下是采用广播的机制来实现fragment中adapter的数据的更新;这样做主要是考虑到工作线程的任务加载完成,而具体的对应刷新的activity可能还没有启动;

另外,基于接口隔离原则,如果用handler进行通信的话,则不能很好的满足这一原则;

你要是周期比较长 用广播好些吧

应该与周期关系不是很密切。最主要的原因是两条线成是双向通信。

Handler类似于P2P的通信。
广播则类似于一个server端,用来处理分发不同线程的请求,从控制器的角度来说用广播更好一点。

一般使用Handler的,多用于子线程处理事务,完成时告知主线程这一类的情况。
而类似楼主所说的多条线程之间需要频繁交互的话,广播是个很好的选择,并且结构清晰,只是不知道广播的性能与handler相比会怎么样。

⑤ 安卓应用程序间的通讯

你是说两个应用之间还是单个应用的进程之间?
应用程序之间共享数据其实可以使用shareperference 或者 sqlite就行 只是实时操作而已 系统资源消耗比较大。
如果是线程间通信可以使用类似handler和runable传参数。
如果是进程间通信的话可以使用远程服务,AIDL作为中间接口,一个服务端一个客户端数据就可以交互。

⑥ Android中线程与线程,进程与进程之间如何通信

使用handler发送message,消息队列排队

进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。
进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。
线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU。

⑦ Android 进程间通信的几种实现方式

Android 进程间通信的几种实现方式

主要有4种方式:

这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。

主要实现原理:

由于应用程序之间不能共享内存。为了在不同应用程序之间交互数据(跨进程通讯),AndroidSDK中提供了4种用于跨进程通讯的方式进行交互数据,实现进程间通信主要是使用sdk中提供的4组组件根据实际开发情况进行实现数据交互。

详细实现方式:

Acitivity实现方式

Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过 Intent构造方法的第2个参数指定)。 在android系统中有很多应用程序提供了可以跨进程访问的Activity,例如,下面的代码可以直接调用拨打电话的Activity。

java">IntentcallIntent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:12345678");
startActivity(callIntent);


Content Provider实现方式

Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)

应用程序可以利用Content Provider完成下面的工作

1. 查询数据
2. 修改数据
3. 添加数据
4. 删除数据

Broadcast 广播实现方式

广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。这就象电台进行广播一样,听众只能被动地收听,而不能主动与电台进行沟通。在应用程序中发送广播比较简单。只需要调用sendBroadcast方法即可。该方法需要一个Intent对象。通过Intent对象可以发送需要广播的数据。


Service实现方式

常用的使用方式之一:利用AIDL Service实现跨进程通信

这是我个人比较推崇的方式,因为它相比Broadcast而言,虽然实现上稍微麻烦了一点,但是它的优势就是不会像广播那样在手机中的广播较多时会有明显的时延,甚至有广播发送不成功的情况出现。

注意普通的Service并不能实现跨进程操作,实际上普通的Service和它所在的应用处于同一个进程中,而且它也不会专门开一条新的线程,因此如果在普通的Service中实现在耗时的任务,需要新开线程。

要实现跨进程通信,需要借助AIDL(Android Interface Definition Language)。Android中的跨进程服务其实是采用C/S的架构,因而AIDL的目的就是实现通信接口。


总结

跨进程通讯这个方面service方式的通讯远远复杂于其他几种通讯方式,实际开发中Activity、Content Provider、Broadcast和Service。4种经常用到,学习过程中要对没种实现方式有一定的了解。

⑧ 线程间通信方式有哪些

多线程通信的方法主要有以下三种:
1.全局变量

进程中的线程间内存共享,这是比较常用的通信方式和交互方式。
注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化。

2.Message消息机制
常用的Message通信的接口主要有两个:PostMessage和PostThreadMessage,

PostMessage为线程向主窗口发送消息。而PostThreadMessage是任意两个线程之间的通信接口。

2.1.PostMessage()
函数原型:
B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

参数:
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
HWND.BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口
和弹出式窗口。消息不被寄送到子窗口。
NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零值:如果函数调用失败,返回值是零。
MS还提供了SendMessage方法进行消息间通讯,SendMessage(),他和PostMessage的区别是:

SendMessage是同步的,而PostMessage是异步的。SendMessage必须等发送的消息执行之后,才返回。
2.2.PostThreadMessage()

PostThreadMessage方法可以将消息发送到指定线程。
函数原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam, LPARAM lParam);

参数除了ThreadId之外,基本和PostMessage相同。
目标线程通过GetMessage()方法来接受消息。

注:使用这个方法时,目标线程必须已经有自己的消息队列。否则会返回ERROR_INVALID_THREAD_ID错误。可以用
PeekMessage()给线程创建消息队列。
3.CEvent对象

CEvent为MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步。

⑨ Android 线程间通信有哪几种方式

Android 的广播机制 在 Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。下面我画一张粗略的图来帮助大家理解广播的运行机制。 Android 中有各式各样的广播,各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android 接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要 Android 系统为我们做筛选。 案例分析: 一个经典的电话黑名单,首先通过将黑名单号码保存在数据库里面,当来电时,我们接收到来电广播并将黑名单号码与数据库中的某个数据做匹配,如果匹配的话则做出相应的处理,比如挂掉电话、比如静音等等。。。 Demo 分析: 下面通过一个小DEMO 来讲解一下广播在Android 中如何编写,在Demo中我们设置了一个按钮为按钮设置点击监听通过点击发送广播,在后台中接收到广播并打印LOG信息。代码如下: BroadCastActivity 页面代码 public class BroadCastActivity extends Activity { public static final String ACTION_INTENT_TEST = "com.terry.broadcast.test"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.Button01); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(ACTION_INTENT_TEST); sendBroadcast(intent); } }); } } 接收器代码如下: public class myBroadCast extends BroadcastReceiver { public myBroadCast() { Log.v("BROADCAST_TAG", "myBroadCast"); } @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Log.v("BROADCAST_TAG", "onReceive"); } } Android 广播的生命周期 在上面的接收器中,继承了BroadcastReceiver 并重写了它的onReceive 并构造了一个函数,下面通过图片来一步一步认识 Android 广播的生命周期。当我点击一下按钮,它向Android 发送了一个广播,如下图: 这时我们再点击一下按钮,它还是会再向 Android 系统发送广播,此时日志信息如下: 下面本人画一张图像,描述了Android 中广播的生命周期,其次它并不像Activity 一样复杂,运行原理很简单如下图: 下面来看一下SDK给出的解释: 大意为:如果一个广播处理完onReceive 那么系统将认定此对象将不再是一个活动的对象,也就会finished掉它。 至此,大家应该能明白 Android 的广播生命周期的原理,代码也不用多介绍,很简单的一个发送广播并处理广播的Demo。 Android 如何判断并筛选广播? 前 面说过 Android 的广播有各式各样,那么Android 系统是如何帮我们处理我们需要哪种广播并为我们提供相应的广播服务呢?这里有一点需要大家注意,每实现一个广播接收类必须在我们应用程序中的 manifest 中显式的注明哪一个类需要广播,并为其设置过滤器,如下图: Tip:action 代表一个要执行的动作,在Andriod 中有很action 比如 ACTION_VIEW,ACTION_EDIT 那么有些人会问了,如果我在一个广播接收器中要处理多个动作呢?那要如何去处理? 在Android 的接收器中onReceive 以经为我们想到的,同样的你必须在Intent-filter 里面注册该动作,可以是系统的广播动作也可以是自己需要的广播,之后你之需要在onReceive 方法中,通过intent.getAction()判断传进来的动作即可做出不同的处理,不同的动作。具体大家可以去尝试测试一下。 小结: 在Android 中如果要发送一个广播必须使用sendBroadCast 向系统发送对其感兴趣的广播接收器中。 使用广播必须要有一个intent 对象必设置其action动作对象 使用广播必须在配置文件中显式的指明该广播对象 每次接收广播都会重新生成一个接收广播的对象 在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理 Android广播机制(两种注册方法) 在android下,要想接受广播信息,那么这个广播接收器就得我们自己来实现了,我们可以继承BroadcastReceiver,就可以有一个广播接受器了。有个接受器还不够,我们还得重写BroadcastReceiver里面的onReceiver方法,当来广播的时候我们要干什么,这就要我们自己来实现,不过我们可以搞一个信息防火墙。具体的代码: public class SmsBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Object[] object = (Object[])bundle.get("ps"); SmsMessage sms[]=new SmsMessage[object.length]; for(int i=0;i { sms[0] = SmsMessage.createFromP((byte[])object[i]); Toast.makeText(context, "来自"+sms[i].getDisplayOriginatingAddress()+" 的消息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show(); } //终止广播,在这里我们可以稍微处理,根据用户输入的号码可以实现短信防火墙。 abortBroadcast(); } } 当实现了广播接收器,还要设置广播接收器接收广播信息的类型,这里是信息:android.provider.Telephony.SMS_RECEIVED 我们就可以把广播接收器注册到系统里面,可以让系统知道我们有个广播接收器。这里有两种,一种是代码动态注册: //生成广播处理 smsBroadCastReceiver = new SmsBroadCastReceiver(); //实例化过滤器并设置要过滤的广播 IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); //注册广播 BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter); 一种是在AndroidManifest.xml中配置广播 package="spl.broadCastReceiver" android:versionCode="1" android:versionName="1.0"> android:label="@string/app_name"> 两种注册类型的区别是: 1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。 2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。 BroadcastReceiver用于监听被广播的事件 必须被注册,有两种方法: 1、在应用程序的代码中注册 注册BroadcastReceiver: registerReceiver(receiver,filter); 取消注册BroadcastReceiver: unregisterReceiver(receiver); 当BroadcastReceiver更新UI,通常会使用这样的方法注册。启动Activity时候注册BroadcastReceiver,Activity不可见时候,取消注册。 2、在androidmanifest.xml当中注册 使用这样的方法注册弊端:它会始终处于活动状态,毕竟是手机开发,cpu和电源资源比较少,一直处于活动耗费大,不利。

⑩ 大神救命啊 android线程间通信 handler message之类的

线程间通讯(三种方式)::
public class AnrActivity extends Activity implements OnClickListener {
TextView text;
Handler handler;
ProgressBar bar;

private class MyAsycnTask extends AsyncTask<URL, Integer, String>{

@Override
protected void onProgressUpdate(Integer... values) {

bar.setProgress(values[0]);
text.setText("进度:"+values[0]+"%");
super.onProgressUpdate(values);
}
@Override
protected String doInBackground(URL... params) {
for (int i = 0; i <100; i++) {
try {
publishProgress(i+1);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "success";
}
@Override
protected void onPostExecute(String result) {
text.setText(result);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button down = (Button) this.findViewById(R.id.button1);
Button receiver = (Button) this.findViewById(R.id.button2);
Button update = (Button)this.findViewById(R.id.button3);
bar = (ProgressBar)this.findViewById(R.id.progressBar1);
text = (TextView)this.findViewById(R.id.text);

update.setOnClickListener(this);
down.setOnClickListener(this);
receiver.setOnClickListener(this);

}

@Override
public void onClick(final View v) {

switch (v.getId()) {
case R.id.button1:
//通过 Asycntask 进行通讯
MyAsycnTask myAsycnTask = new MyAsycnTask();
myAsycnTask.execute(null);
break;

case R.id.button2:
//通过发送通知进行通讯
Intent intent = new Intent();
intent.putExtra("test", "receiver");
intent.setAction("com.tarena.test");
sendBroadcast(intent);//发送通知
break;

case R.id.button3:
// 通过 new Thread()或者runOnUiThread()或者Handler 实现
new Thread(){
public void run() {
CommontUtils.timeConsuming(2);
Runnable action = new Runnable() {

@Override
public void run() {
Toast.makeText(AnrActivity.this, "update_success", 0).show();
text.setText("update_success");

}
};
//runOnUiThread(action);
//handler.post(action);
v.post(action);

}

}.start();
break;

热点内容
qq刷红包脚本 发布:2024-05-03 16:16:54 浏览:769
c服务编译耗时优化原理及实例 发布:2024-05-03 15:35:26 浏览:15
ue编程 发布:2024-05-03 15:34:40 浏览:610
经典的c语言程序 发布:2024-05-03 15:03:24 浏览:859
工程加密网 发布:2024-05-03 14:59:55 浏览:292
吃冰球解压 发布:2024-05-03 14:59:10 浏览:895
编译芯片发烫 发布:2024-05-03 14:59:05 浏览:549
优化算法pdf 发布:2024-05-03 14:18:10 浏览:291
python算法书 发布:2024-05-03 14:14:25 浏览:736
方舟怎么加入服务器闪退 发布:2024-05-03 14:05:27 浏览:491