當前位置:首頁 » 安卓系統 » 安卓線程之間通訊用什麼對象

安卓線程之間通訊用什麼對象

發布時間: 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;

熱點內容
顯卡怎麼保存配置 發布:2024-04-20 09:28:52 瀏覽:596
校園交易網站源碼 發布:2024-04-20 09:18:54 瀏覽:701
江蘇北斗授時伺服器ip雲空間 發布:2024-04-20 08:53:50 瀏覽:931
dedecms批量上傳圖片 發布:2024-04-20 08:42:11 瀏覽:966
酷q如何編譯 發布:2024-04-20 08:41:27 瀏覽:79
安卓手機數字人民幣怎麼下載 發布:2024-04-20 08:38:21 瀏覽:114
access如何配置資料庫 發布:2024-04-20 08:37:35 瀏覽:504
手寫輸入演算法 發布:2024-04-20 08:29:31 瀏覽:258
朝夕源碼 發布:2024-04-20 08:24:15 瀏覽:276
minilinux 發布:2024-04-20 08:23:38 瀏覽:50