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
這個方法略,如果知道上面兩種方法,這個方法基本很少會用到。
相關文章
- Activity和Service跨程式通訊的兩種方式
- Android中Service的啟動方式及Activity與Service的通訊方式Android
- Activity之間的通訊方式
- Vue元件之間通訊的三種方式Vue元件
- Fragment與Activity通訊Fragment
- Android 活動(activity)和服務(service)進行通訊Android
- 驅動和應用層的三種通訊方式
- nginx與php-fpm通訊的兩種方式NginxPHP
- vue通訊的N種方式Vue
- T面試題:程式間的通訊方式有哪幾種?面試題
- 主機和虛擬機器的三種通訊方式虛擬機
- 什麼是程式間通訊?Linux程式間通訊有幾種方式?Linux
- 程式間通訊是什麼?Linux程式間通訊有幾種方式?Linux
- 串列埠通訊與其他通訊方式相比有什麼優勢?串列埠
- 程式間的幾種通訊方式
- 幾種程式間的通訊方式
- 程式間的8種通訊方式
- React中元件通訊的幾種方式React元件
- 程式間通訊方式有哪些?
- 啟動另外的一個應用程式的Activity(三種方式)
- Android 三種播放視訊的方式Android
- iOS之視訊的三種播放方式iOS
- React的6種通訊方式(附帶例子)React
- Vue3 的8種元件通訊方式Vue元件
- 程式間的五種通訊方式介紹
- iOS App間常用的五種通訊方式iOSAPP
- React中元件間通訊的幾種方式React元件
- android Fragments詳解五:與activity通訊AndroidFragment
- Activity 與 Fragment 通訊(99%)完美解決方案Fragment
- Web發展中通訊的方式有哪些Web
- Android的activity的四種啟動方式Android
- Windows程式間各種通訊方式淺談Windows
- 程式間的五種通訊方式介紹-詳解
- Linux程式間通訊的6種不同方式Linux
- Android中Activity的四種啟動方式Android
- activemq的兩種基本通訊方式的使用及總結MQ
- Linux程式間通訊有幾種方式?這8個你都知道嗎?Linux
- 程式間的八種通訊方式----共享記憶體是最快的 IPC 方式記憶體