一個簡單的demo學習Android遠程Service(AIDL的使用)

來源:互聯網
上載者:User

原文地址

http://miloisbadboy.com/archives/109

這是milo很早之前寫在論壇上的一個文章,現在整理出來,milo也複習一下
一般來說Android 的四大組件都是運行在同一個進程中的,但遠程Service運行在不同的進程裡。這進程間的通訊是使用了Android Binder機制。Android 中Service 有本地Service和遠程Service之分,本地Service用法比較簡單,而遠程Service用法稍微要複雜一些。下面就是一個使用AIDL的用法。

AIDL即android 介面定義語言,概念不多說,網上有太多的文章介紹概念。本文只想說明一下aidl的用法。由於最近開發一個播放器的項目使用了aidl。aidl是解決處理序間通訊用的。在本例中就是Activity(即client端)與Service(即服務端)的通訊。
首先,定義Aidl檔案,如Service中暴露給Activity的介面可以定義在aidl檔案中,反之也一樣。本文中,Service給Activity使用介面檔案是ServiceAIDL.aidl
<pre lang="LANGUAGE" line="1">
package com.miloisbadboy.aidl;
import com.miloisbadboy.aidl.ActivityAIDL;
/**
*Service中暴露給Activity的介面可以定義在aidl檔案中
*/
interface ServiceAIDL{
void callService();
/**
*在Activity中註冊ActivityAIDL到Service中,使Service中可以調用ActivityAIDL中的方法
**/
void registActivityCallBack(ActivityAIDL callBack);
}
</pre>
Activity給Service中使用的ActivityAIDL.aidl
<pre lang="LANGUAGE" line="1">
package com.miloisbadboy.aidl;
/**
*Activity中暴露給Service的介面可以定義在aidl檔案中
*/
interface ActivityAIDL{
void callActivity();
}
</pre>
上面兩個aidl在會自動在gen目錄下產生對應的java檔案。
第二步,寫Service。寫一個MyService繼承於Service類,並在onBind()方法中 返回ServiceAidl.Stub對象
具體看下面代碼
MyService.java
<pre lang="LANGUAGE" line="1">
package com.miloisbadboy;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;

import com.miloisbadboy.aidl.ActivityAIDL;
import com.miloisbadboy.aidl.ServiceAIDL;

/**
* 遠程服務
*/
public class MyService extends Service {
public static final String SERVICE_NAME = "com.miloisbadboy.start.MyService";
public static final String TAG = "MyService";

private ActivityAIDL activityAIDL;

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

private ServiceAIDL.Stub mBinder = new ServiceAIDL.Stub() {

@Override
public void callService() throws RemoteException {
Log.i(TAG, "Activity Call Service's method ****** callService()");
Toast.makeText(getApplicationContext(), "Call Service's method ****** callService()",
1000).show();

activityAIDL.callActivity();
}

@Override
public void registActivityCallBack(ActivityAIDL callBack) throws RemoteException {
activityAIDL = callBack;
}

};
}

</pre>
MyService中有ActiviyAIDL的一個引用,此類型的執行個體是在ServiceAIDL.Stud這個代理中得到的,即是在registActivityCallBack(ActivityAIDL callBack)方法中對其賦值,這個方法是在Activity中將ActivityAIDL的介面註冊到Service中去的。
在ServiceAidl.Stub mBinder = new ServiceAidl.Stub(){}裡面的callService() 和registActivityAidl(ActivityAidl activityAidl)方法就是在Activity將會被調用到的。
最後看一個Activity類
<pre lang="LANGUAGE" line="1">
package com.miloisbadboy;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.miloisbadboy.aidl.ActivityAIDL;
import com.miloisbadboy.aidl.ServiceAIDL;
/**
* 測試遠程Service
*/
public class TestAIDLActivity extends Activity implements OnClickListener{

private static final String TAG = "TestAIDLActivity";

private Button start;
private Button stop;
private Button callService;
/**
* service call back
*/
private ServiceAIDL serviceAIDL;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

start = (Button)findViewById(R.id.start_service);
stop = (Button)findViewById(R.id.stop_service);
callService = (Button)findViewById(R.id.call_service);

start.setOnClickListener(this);
stop.setOnClickListener(this);
callService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v == start){
Intent service = new Intent(MyService.SERVICE_NAME);
//綁定Service 並將ServiceConnection的執行個體傳入
bindService(service, serviceConn, Context.BIND_AUTO_CREATE);
stop.setVisibility(View.VISIBLE);
}else if(v == stop){
unbindService(serviceConn);
}else{
try {
if(serviceAIDL!=null){
serviceAIDL.callService();
}else {
Toast.makeText(this, "Service is not started!", 1000).show();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
private ServiceConnection serviceConn = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {
serviceAIDL = null;
Toast.makeText(getApplication(), "Service is unbind!", 1000).show();
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceAIDL = ServiceAIDL.Stub.asInterface(service);
//在此將Activity暴露給Service的介面實現註冊到Service中去
try {
serviceAIDL.registActivityCallBack(activityAidl);
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
/**
* 在activity中實現ActivityAIDL介面
*/
private ActivityAIDL activityAidl = new ActivityAIDL.Stub() {

@Override
public void callActivity() throws RemoteException {
Log.i(TAG, "callActivity()");
Toast.makeText(getApplicationContext(), "service call activity", 1000).show();
}
};
}
</pre>
在activity中有三個按鈕分別為 start service ; stop service ;callService
各個按鈕的動作顧名思義啦。特別注意到。在Activity ServiceConnection中 會通過ServiceAIDL.Stub.asInterface(service)得到ServiceAIDL的執行個體,並且將activityAidl的引用註冊到了Service中。
在start service 按鈕事件裡,通過bindService(service, serviceConn, Context.BIND_AUTO_CREATE)將Service 與Activity綁定。

這個程式跑起來的順序是,啟動Activity後,並start service後 點擊callServiceBtn,就會調用MyService中實現的callService()介面,而在callService中又調用了activityAidl即Activity的回調callActivity()方法
這樣就類比了 Activity 與Service兩個進程間的通訊,即相互調用了對方的對象。
本文只是對Aidl的用法做了一個小小總結,算是拋磚引玉吧。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.