AIDL(2):通過傳輸複雜物件,aidl傳輸對象
IPC通過AIDL傳遞複雜物件
1.定義資料轉送對象
Person.aidl檔案:
Person.java檔案中:
(1)實現parcelable介面
(2)提供一個名為CREATOR的static final屬性
package com.liujun.aidl;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String name;
private int sex;
public Person(){
}
public Person(Parcel source){
readFromParcel(source);
}
//必須提供一個名為CREATOR的static final屬性 該屬性需要實現android.os.Parcelable.Creator<T>介面
public static final Parcelable.Creator<Person> CREATOR =new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
//注意讀取變數和寫入變數的順序應該一致 不然得不到正確的結果
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(sex);
}
//注意讀取變數和寫入變數的順序應該一致 不然得不到正確的結果
public void readFromParcel(Parcel source) {
name = source.readString();
sex = source.readInt();
}
//////////////////////////////////////////////////////////////////
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
2.定義遠程服務介面和服務元件
IGreetService.aidl檔案:
package com.liujun.aidl;
import com.liujun.aidl.Person;
interface IGreetService{
String greet(in Person person);
}
AIDLService.java檔案:
package com.liujun.service;
import com.liujun.aidl.IGreetService;
import com.liujun.aidl.Person;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class AIDLService extends Service {
private static final String TAG = "liujun";
@Override
public void onCreate() {
Log.i(TAG, "onCreate() called");
super.onCreate();
}
@Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "onBind() called");
return stub;
}
//服務介面執行個體對象
IGreetService.Stub stub=new IGreetService.Stub() {
@Override
public String greet(Person person) throws RemoteException {
Log.i(TAG, "greet(Person person) called");
return ServiceMethod(person);
}
};
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind() called");
return true;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy() called");
}
/////////////////-----------------------------------
/**
* 服務元件方法
* @param person
* @return
*/
public String ServiceMethod(Person person){
String greeting = "hello, " + person.getName();
switch (person.getSex()) {
case 0:
greeting = greeting + ", you're handsome."; 工程代碼
break;
case 1:
greeting = greeting + ", you're beautiful.";
break;
}
return greeting;
}
}
註冊服務:
<!-- 佈建服務組件 -->
<service android:name="com.liujun.service.AIDLService">
<intent-filter>
<action android:name="android.intent.action.AIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
3.用戶端程式複製服務端程式資料轉送對象和介面檔案
4.綁定遠程服務,調用遠程服務方法,傳輸複雜物件
package com.liujun.parcelableclient;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.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.example.parcelableclient.R;import com.liujun.aidl.IGreetService;import com.liujun.aidl.Person;public class MainActivity extends Activity { //控制項 private Button bindBtn; private Button greetBtn; private Button unbindBtn; private boolean mBound=false;//是否綁定遠程服務 //遠程服務介面對象 private IGreetService iService; //擷取遠程服務介面對象 private ServiceConnection conn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {iService=IGreetService.Stub.asInterface(service);mBound=true;} @Overridepublic void onServiceDisconnected(ComponentName name) {mBound=false;iService=null;}}; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindBtn=(Button) this.findViewById(R.id.bindBtn);greetBtn=(Button) this.findViewById(R.id.greetBtn);unbindBtn=(Button) this.findViewById(R.id.unbandBtn);//註冊點擊監聽器MyListener listener=new MyListener();bindBtn.setOnClickListener(listener);greetBtn.setOnClickListener(listener);unbindBtn.setOnClickListener(listener);}/** * 事件處理器 * @author asus * */private class MyListener implements OnClickListener{@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.bindBtn://綁定遠程服務Intent intent = new Intent("android.intent.action.AIDLService"); bindService(intent, conn, Context.BIND_AUTO_CREATE); //設定按鈕狀態 bindBtn.setEnabled(false); greetBtn.setEnabled(true); unbindBtn.setEnabled(true); break;case R.id.greetBtn: try { Person person = new Person(); person.setName("liujun"); person.setSex(0); String retVal = iService.greet(person); Toast.makeText(MainActivity.this, retVal, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); } break;case R.id.unbandBtn: unbindService(conn); bindBtn.setEnabled(true); greetBtn.setEnabled(false); unbindBtn.setEnabled(false); break;}}}@Overrideprotected void onDestroy() {super.onDestroy();if (mBound) {unbindService(conn);iService=null;}}}工程代碼http://download.csdn.net/detail/u010739551/7710977
怎在Android中使用AIDL設計遠程介面麻煩告訴我
在Android平台,一個進程通常不能訪問另一個進程的記憶體空間,所以要想對話,需要將對象分解成作業系統可以理解的基本單元,並且有序地通過進程邊界。
通過代碼來實現這個資料轉送過程是冗長乏味的,Android提供了AIDL工具來處理這項工作。AIDL(AndroidInterfaceDefinitionLanguage)是一種IDL語言,用於產生可以在Android裝置上兩個進程之間進行處理序間通訊(IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如Service)對象的操作,就可以使用AIDL產生可序列化的參數。AIDLIPC機制是面向介面的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在用戶端和實現端傳遞資料。
一、使用AIDL實現IPC(ImplementingIPCUsingAIDL)
使用AIDL實現IPC服務的步驟是:第一,建立.aidl檔案。該檔案(YourInterface.aidl)定義用戶端可用的方法和資料介面。第二,在makefile檔案中加入.aidl檔案(Eclipse中的ADT外掛程式提供管理功能)。Android包括名為AIDL的編譯器,位於tools/檔案夾。第三,實現介面-AIDL編譯器從AIDL介面檔案中利用Java語言建立介面。該介面有一個繼承的命名為Stub的內部抽象類別(已實現一些IPC調用的附加方法),要做的就是建立一個繼承於YourInterface.Stub的類,並且實現在.aidl檔案中聲明的方法。第四,向用戶端公開介面。如果是編寫服務,應該繼承Service並且重載Service.onBind(Intent)以返回實現了介面的對象執行個體。
二、建立.aidl檔案(Createan.aidlFile)
AIDL使用簡單的文法來聲明介面,描述其方法以及方法的參數和傳回值。這些參數和傳回值可以是任何類型,甚至是其他AIDL產生的介面。需要注意的是,必須匯入所有非內建類型。AIDL能支援的資料類型有以下幾類:第一,Java程式設計語言的主要類型(int,boolean等),不需要import語句。第二,通常引引用方式傳遞的其他AIDL產生的介面,必須要import語句聲明。第三,實現了Parcelableprotocol以及按值傳遞的自訂類,必須要import語句聲明。另外,還有一些不需要import語句,如String等。
三、實現介面(ImplementingtheInterface)
AIDL產生了與.aidl檔案同名的介面,如果使用Eclipse外掛程式,AIDL會作為編譯過程的一部分自動運行(不需要先運行AIDL再編譯項目);如果沒有外掛程式,就要先運行AIDL。
產生的介面包含一個名為Stub的抽象的內部類,該類聲明了所有.aidl中描述的方法,Stub還定義了少量的輔助方法,尤其是asInterface(),通過它獲得IBinder(當applicationContext.bindService()成功調用時傳遞到用戶端的onServiceConnected())並且返回用於調用IPC方法的介面執行個體。要實現自己的介面,就從YourInterface.Stub類繼承,然後實現相關方法(可以建立.aidl檔案實現stub方法而不用在中間編譯,Android編譯過程會在.java檔案之前處理.aidl檔案)。
在完成了介面的實現後,需要向用戶端暴露介面,也就是發布服務。實現的方法是繼承Service,然後實現以Service.onB......餘下全文>>
struts2資料轉送問題
當Action設定了某個屬性值後,struts2將這些屬性值全部封在一個com.opensymphony.xwork2.util.ValueStack類型的對像裡,然後再將ValueStack對像以名稱“struts.valueStack”設定在request的請求屬性裡(request.setAttribute("struts.valuestack");),標籤便可通過請求屬性“struts.valueStack”將action中設定的屬性取出(org.apache.struts2.views.jsp.TagUtils.getStack(PageContext pageContext))。詳細內容可查看struts2標籤原始碼......