前端時(shí)間項(xiàng)目運(yùn)用到AIDL,關(guān)于AIDL客戶端以及AIDL服務(wù)端網(wǎng)絡(luò)上沒有一個(gè)比較完備的Demo.
站在用戶的角度思考問題,與客戶深入溝通,找到高港網(wǎng)站設(shè)計(jì)與高港網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋高港地區(qū)。
而參考Demo無疑是一個(gè)比較快速的學(xué)習(xí)方法.因此,我寫了一個(gè)Demo.
供大家參考,也非常歡迎大家對(duì)其中寫的不好的地方進(jìn)行指正.
好了,首先簡述下基本功能:
在AIDL 客戶端三個(gè)EditText中輸入三個(gè)值,點(diǎn)擊提交按鈕,將這三個(gè)值傳入到AIDL服務(wù)端進(jìn)行處理.
服務(wù)端處理后會(huì)執(zhí)行客戶端的回調(diào)函數(shù):在AIDL客戶端界面進(jìn)行刷新,并顯示一個(gè)toast.
接下來看看代碼結(jié)構(gòu):
需要注意的是,兩個(gè)工程中com.harlan.demo.aidl包內(nèi)部的文件必須保持一致.
(1)HarlanInfo.java:這是包中唯一的一個(gè)java文件,是一個(gè)數(shù)據(jù)結(jié)構(gòu),該類實(shí)現(xiàn)了Parcelable接口
[java] view plaincopyprint?
package com.harlan.demo.aidl;
import android.os.Parcel;
import android.os.Parcelable;
/**
*
* <一句話功能簡述>
* Parcelable是Android特有的功能,效率比實(shí)現(xiàn)Serializable接口高
*
* @author Administrator
* @version [版本號(hào), 2012-12-10]
* @see [相關(guān)類/方法]
* @since [產(chǎn)品/模塊版本]
*/
public class HarlanInfo implements Parcelable
{
private String name;
private int age;
private String place;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getPlace()
{
return place;
}
public void setPlace(String place)
{
this.place = place;
}
/**
* <默認(rèn)構(gòu)造函數(shù)>
*/
public HarlanInfo()
{
}
/**
* <默認(rèn)構(gòu)造函數(shù)>
*/
public HarlanInfo(Parcel in)
{
//注意順序
name = in.readString();
age = in.readInt();
place = in.readString();
}
/**
* seems meaningless
* return 0;
*/
@Override
public int describeContents()
{
return 0;
}
/**
* 將對(duì)象序列化為一個(gè)Parcel對(duì)象
* 可以將Parcel看成是一個(gè)流,通過writeToParcel把對(duì)象寫到流里面,
* 再通過createFromParcel從流里讀取對(duì)象
* 注意:寫的順序和讀的順序必須一致。
*/
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(name);
dest.writeInt(age);
dest.writeString(place);
}
/**
* 實(shí)例化靜態(tài)內(nèi)部對(duì)象CREATOR實(shí)現(xiàn)接口Parcelable.Creator
* public static final一個(gè)都不能少,內(nèi)部對(duì)象CREATOR的名稱也不能改變,必須全部大寫
*/
public static final Parcelable.Creator
//將Parcel對(duì)象反序列化為HarlanInfo
@Override
public HarlanInfo createFromParcel(Parcel source)
{
HarlanInfo hlInfo = new HarlanInfo(source);
return hlInfo;
}
@Override
public HarlanInfo[] newArray(int size)
{
return new HarlanInfo[size];
}
};
}
(2)HarlanInfo.aidl :協(xié)同HarlanInfo.java文件"作戰(zhàn)",缺一不可.
[java] view plaincopyprint?
package com.harlan.demo.aidl;
parcelable HarlanInfo;
(3)ICallBack.aidl:
這是客戶端回調(diào)方法的接口,在客戶端實(shí)現(xiàn)其具體方法,在服務(wù)端調(diào)用執(zhí)行.
[java] view plaincopyprint?
package com.harlan.demo.aidl;
interface ICallBack{
/**
*callback of AIDLClient
*handle by server
**/
void handleByServer(String param);
}
(4)ExecuteService.aidl:
這是從服務(wù)端獲取數(shù)據(jù)方法的接口,在服務(wù)端實(shí)現(xiàn)其具體方法,在客戶端調(diào)用執(zhí)行.
參數(shù)info是由用戶輸入的數(shù)據(jù)構(gòu)成的,同時(shí)傳遞的還要客戶端回調(diào)方法的句柄,從而服務(wù)端可以調(diào)用客戶端的回調(diào)方法.
該方法返回一個(gè)HarlanInfo的數(shù)據(jù)類型,客戶端獲得此數(shù)據(jù),在界面上進(jìn)行相應(yīng)的顯示.
[java] view plaincopyprint?
package com.harlan.demo.aidl;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
interface ExecuteServiceAIDL
{
/**
*get info from server and
*Transfer a callback methods handle;
*if occur error ,will be return null
*對(duì)于非基本數(shù)據(jù)類型和String和CharSequence類型,要加上方向指示
*包括in、out和inout,in表示由客戶端設(shè)置,out表示由服務(wù)端設(shè)置,inout是兩者均可設(shè)置。
*/
HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);
}
好了,現(xiàn)在對(duì)com.harlan.demo.aidl包已經(jīng)大致了解,build一下project,發(fā)現(xiàn)gen文件夾下面多出來一個(gè)包:
包中文件可以隨便看看,不看也沒事.因?yàn)槟阒灰诳蛻舳朔?wù)端相應(yīng)的位置實(shí)現(xiàn)對(duì)應(yīng)的接口就可以了.
先來看看服務(wù)端,因?yàn)榉?wù)端相對(duì)簡單些,不需要界面什么的,只是一個(gè)Service.
上代碼:
[java] view plaincopyprint?
package com.harlan.demo.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
public class AIDLService extends Service
{
public static final String TAG = "AIDLService";
private ICallBack mCallBack;
/**
* 綁定服務(wù)
*/
@Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return mBinder;
}
/**
* 創(chuàng)建服務(wù)
*/
@Override
public void onCreate()
{
super.onCreate();
}
/**
* 銷毀服務(wù)
*/
@Override
public void onDestroy()
{
super.onDestroy();
}
/**
* 啟動(dòng)服務(wù)
*/
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
}
/**
* 解綁服務(wù)
*/
@Override
public boolean onUnbind(Intent intent)
{
mCallBack = null;
return super.onUnbind(intent);
}
ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()
{
//這里實(shí)現(xiàn)了getServiceHarlanInfo接口
@Override
public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)
throws RemoteException
{
Log.d(TAG,"getServerHarlanInfo");
mCallBack = icallback;
mCallBack.handleByServer("The msg is from server");
HarlanInfo newInfo = new HarlanInfo();
newInfo.setName(info.getName().toLowerCase());
newInfo.setAge(info.getAge() + 10);
newInfo.setPlace("Home");
return newInfo;
}
};
}
一目了然,服務(wù)端主要的功能就是實(shí)現(xiàn)了aidl中的getServerHarlanInfo(HarlanInfo info, ICallBack icallback)接口.返回了一個(gè)mBinder供客戶端調(diào)用.
寫好了服務(wù),還得在Manifest文件里面配置一下:
[java] view plaincopyprint?
android:name=".AIDLService">
lt;/service>
服務(wù)端寫好了,就來客戶端的了.客戶端主要是一個(gè)activity,界面相對(duì)簡單,如圖所示:
界面布局相對(duì)簡單,就不貼代碼了.
下面貼ClientActivity的代碼:
[java] view plaincopyprint?
package com.harlan.demo.activity;
import android.app.Activity;
import android.content.ComponentName;
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.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
public class ClientActivity extends Activity
{
public static final String TAG = "ClientActivity";
private static final String BIND_ACTION = "com.harlan.demo.aidl.service";
private EditText mEditTextName;
private EditText mEditTextAge;
private EditText mEditTextPlace;
private Button mButtonCommit;
private ExecuteServiceAIDL executeService;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
getView();
//用戶點(diǎn)擊提交按鈕,將數(shù)據(jù)傳至服務(wù)端進(jìn)行處理
mButtonCommit.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
//綁定服務(wù)
getServiceConnect();
}
});
}
private void getView()
{
mEditTextName = (EditText)findViewById(R.id.editText_name);
mEditTextAge = (EditText)findViewById(R.id.editText_age);
mEditTextPlace = (EditText)findViewById(R.id.editText_place);
mButtonCommit = (Button)findViewById(R.id.button_commit);
}
private void getServiceConnect()
{
Intent it = new Intent();
it.setAction(BIND_ACTION);
startService(it);
bindService(it, mserviceConnection, BIND_AUTO_CREATE);
}
ServiceConnection mserviceConnection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName name)
{
Log.d(TAG, "onServiceDisconnected");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.d(TAG, "onServiceConnected");
//獲取服務(wù)端傳過來的IBinder對(duì)象,通過該對(duì)象調(diào)用服務(wù)端的方法
executeService = ExecuteServiceAIDL.Stub.asInterface(service);
if (executeService != null)
{
handlerInfo();
}
}
};
private void handlerInfo()
{
String mName;
int mAge;
String mPlace;
if (mEditTextName.getText().toString().equals(""))
{
mEditTextName.setText("Harlan");
mName = "Harlan";
}
else
{
mName = mEditTextName.getText().toString();
}
if (mEditTextAge.getText().toString().equals(""))
{
mAge = 22;
}
else
{
mAge = Integer.parseInt(mEditTextAge.getText().toString());
}
if (mEditTextPlace.getText().toString().equals(""))
{
mPlace = "Nanjing";
}
else
{
mPlace = mEditTextPlace.getText().toString();
}
HarlanInfo mInfo = new HarlanInfo();
mInfo.setName(mName);
mInfo.setAge(mAge);
mInfo.setPlace(mPlace);
try
{
HarlanInfo serverInfo = new HarlanInfo();
//調(diào)用服務(wù)端的方法
serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);
//更新界面
mEditTextName.setText(serverInfo.getName());
mEditTextAge.setText(String.valueOf(serverInfo.getAge()));
mEditTextPlace.setText(serverInfo.getPlace());
unbindService(mserviceConnection);
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
ICallBack.Stub mCallBack = new ICallBack.Stub()
{
//客戶端回調(diào)方法的具體實(shí)現(xiàn)
@Override
public void handleByServer(String param)
throws RemoteException
{
Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();
}
};
}
服務(wù)端調(diào)用客戶端回調(diào)方法,在界面上顯示一個(gè)toast.客戶端根據(jù)服務(wù)端傳回來的數(shù)據(jù),刷新界面.
最后運(yùn)行結(jié)果如圖所示:
具體的Demo已經(jīng)上傳至CSDN,下載地址:http://download.csdn.net/detail/singleton1900/4928804