Activity與Service通訊的方式有三種:
在部落格園看到的,看著挺不錯的,借來分享下
</pre><p></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-size:14px; line-height:25px; font-family:Helvetica,Tahoma,Arial,sans-serif"><span style="margin: 0px; padding: 0px;"><span style="margin:0px; padding:0px">繼承Binder類</span></span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-size:14px; line-height:25px; font-family:Helvetica,Tahoma,Arial,sans-serif"><span style="margin:0px; padding:0px; font-size:14px"> 這個方式只有當你的Acitivity和Service處於同一個Application和程式時,才可以用,比如你後臺有一個播放背景音樂的Service,這時就可以用這種方式來進行通訊。</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-size:14px; line-height:25px; font-family:Helvetica,Tahoma,Arial,sans-serif"><span style="margin:0px; padding:0px; font-size:14px">用例子來說明其使用方法:</span></p><p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-size:14px; line-height:25px; font-family:Helvetica,Tahoma,Arial,sans-serif"><span style="margin:0px; padding:0px; font-size:14px"> 1. 來看Service的寫法:</span></p><pre code_snippet_id="459570" snippet_file_name="blog_20140827_2_3516924" name="code" class="java">public class LocalService extends Service {
// 例項化自定義的Binder類
private final IBinder mBinder = new LocalBinder();
// 隨機數的生成器
private final Random mGenerator = new Random();
/**
* 自定義的Binder類,這個是一個內部類,所以可以知道其外圍類的物件,通過這個類,讓Activity知道其Service的物件
*/
public class LocalBinder extends Binder {
LocalService getService() {
// 返回Activity所關聯的Service物件,這樣在Activity裡,就可呼叫Service裡的一些公用方法和公用屬性
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** public方法,Activity可以進行呼叫 */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
在Service裡定義一個內部類,Binder的子類,通過這個類,把Service的物件傳給Activity,這樣Activity就可以呼叫Service裡的公用方法和公用屬性了,但這種方式,一定要在同一個程式和同一個Application裡。
2. 再看相應Activity的程式碼:
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// 繫結Service,繫結後就會呼叫mConnetion裡的onServiceConnected方法
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// 解綁Service,這樣可以節約記憶體
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** 使用者點選button,就讀取Service裡的隨機數 */
public void onButtonClick(View v) {
if (mBound) {
// 用Service的物件,去讀取隨機數
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/** 定交ServiceConnection,用於繫結Service的*/
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// 已經繫結了LocalService,強轉IBinder物件,呼叫方法得到LocalService物件
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
這裡就是通過IBinder來得到LocalService物件,再去呼叫其Public方法。
使用Messenger
上面的方法只能在同一個程式裡才能用,如果要與另外一個程式的Service進行通訊,則可以用Messenger。
其實實現IPC的方式,還有AIDL,但推薦使用Messenger,有兩點好處:
1. 使用Messenger方式比使用AIDL的方式,實現起來要簡單很多
2. 使用Messenger時,所有從Activity傳過來的訊息都會排在一個佇列裡,不會同時請求Service,所以是執行緒安全的。如果你的程式就是要多執行緒去訪問Service,就可以用AIDL,不然最好使用Messenger的方式。
不過,其實Messenger底層用的就是AIDL實現的,看一下實現方式,先看Service的程式碼:
public class MessengerService extends Service {
/** 用於Handler裡的訊息型別 */
static final int MSG_SAY_HELLO = 1;
/**
* 在Service處理Activity傳過來訊息的Handler
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* 這個Messenger可以關聯到Service裡的Handler,Activity用這個物件傳送Message給Service,Service通過Handler進行處理。
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* 當Activity繫結Service的時候,通過這個方法返回一個IBinder,Activity用這個IBinder建立出的Messenger,就可以與Service的Handler進行通訊了
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
Activity程式碼實現
public class ActivityMessenger extends Activity {
/** 向Service傳送Message的Messenger物件 */
Messenger mService = null;
/** 判斷有沒有繫結Service */
boolean mBound;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// Activity已經繫結了Service
// 通過引數service來建立Messenger物件,這個物件可以向Service傳送Message,與Service進行通訊
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
mBound = false;
}
};
public void sayHello(View v) {
if (!mBound) return;
// 向Service傳送一個Message
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// 繫結Service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// 解綁
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
注意:以上寫的程式碼只能實現從Activity向Service傳送訊息,如果想從Service向Activity傳送訊息,只要把程式碼反過來寫就可以了。
使用AIDL
這個方法略,如果知道上面兩種方法,這個方法基本很少會用到。
相關文章
- Vue元件之間通訊的三種方式Vue元件
- nginx與php-fpm通訊的兩種方式NginxPHP
- vue通訊的N種方式Vue
- 什麼是程式間通訊?Linux程式間通訊有幾種方式?Linux
- 程式間通訊是什麼?Linux程式間通訊有幾種方式?Linux
- 程式間的幾種通訊方式
- T面試題:程式間的通訊方式有哪幾種?面試題
- 串列埠通訊與其他通訊方式相比有什麼優勢?串列埠
- Android中Activity的四種啟動方式Android
- React的6種通訊方式(附帶例子)React
- 程式間的五種通訊方式介紹
- Vue3 的8種元件通訊方式Vue元件
- 程式間通訊方式有哪些?
- Vue.js 父子元件通訊的1212種方式Vue.js元件
- vue3 常用的幾種元件通訊方式Vue元件
- Web發展中通訊的方式有哪些Web
- Application,Activity,Service的建立流程(1)APP
- Application,Activity,Service的建立流程(2)APP
- Linux程式間通訊有幾種方式?這8個你都知道嗎?Linux
- 程式間的五種通訊方式介紹-詳解
- 程式間的八種通訊方式----共享記憶體是最快的 IPC 方式記憶體
- C#winform和php通訊的一種方式request payloadC#ORMPHP
- Rocket MQ傳送訊息的三種方式初析MQ
- Java之異常資訊的三種列印方式Java
- JavaScript的三種引入方式JavaScript
- RocketMQ(6)---傳送普通訊息(三種方式)MQ
- Service Worker學習與實踐(三)——訊息推送
- 程式通訊方式總結與盤點
- 在Linux中,程序間通訊方式有哪些?Linux
- Linux程式間的通訊方式有哪些?Linux入門教程Linux
- 程序通訊方式
- springAOP的三種實現方式Spring
- selenium中的三種等待方式
- WiFi攻擊的三種方式WiFi
- Selenium裡的三種等待方式
- flowable 部署流程的三種方式
- hibernate的三種查詢方式
- 智慧路燈解通訊方式:有線&無線
- Java String 字串拼接的三種方式與效率對比分析Java字串