除了上一篇文章我們提到的通過service提供音樂播放等類似的服務之外,我們還可以通過service將對象傳遞迴來哦,你知道怎麼用嗎,先看例子:
當我們點擊“擷取”時,會從另一個線程的service中擷取一個對象,然後將裡面的內容讀出來。
--------------------------------------------------------------------------------------------
對於aidl實現以對象的方式互動。主要步驟如下:
服務端:
第一:定義一個實體類,這裡是Beauty,定義一個服務介面aidl檔案RemoteBeauty.aidl,這裡有一點需要注意,我們引用自訂的實體類到aidl中時需要通過import匯入包,但是你會發現,即使你匯入了包,還是提示找不到,這時候,你要做的是,建一個以實體類名稱命名的aidl檔案,如Beauty.aidl,在裡面添加一句pracelable Beauty。
第二:開始編寫Beauty,這裡一定要注意,它一定要實現Pracelable介面,該介面是一個序列化的介面,功能和serializable相似,但是功能更加的迅速。此外,在該Beauty內部一定要聲明一個public static final Pracelable.Creator<T>CREATOR對象!!除了裡面的那個T代表實體類之外,其他的都不準改變哦。
第三:在androidManifest.xml中註冊service。並定義好訪問該service的action字串。
用戶端:
用戶端這邊相應的要簡單很多,但是要注意的一點是,要將實體類還有aidl檔案都拷貝過來哦,而且要保證路徑完全一致!!
-------------------------------------------------------------
程式碼範例:
服務端:
Beauty.java
package cn.com.chenzheng_java.service;</p><p>import android.os.Parcel;<br />import android.os.Parcelable;<br />/**<br /> *<br /> * @author chenzheng_java<br /> * @description Parcelable是android提供的一個比serializable效率更高的序號介面<br /> * 這裡必須要繼承Parcelable哦,不序號怎麼可以傳遞……對吧?!<br /> * 在實體類我們要做兩件重要的事情:<br /> * 第一:實現Parcelable介面<br /> * 第二:定義一個Parcelable.Creator類型的CREATOR對象<br /> * 第三:要提供一個Beauty.aidl檔案,其中內容為parcelable Beauty,定義了之後,在其他aidl檔案中引用Beauty時便不會提示出錯了。<br /> * @since 2011/03/18<br /> *<br /> */<br />public class Beauty implements Parcelable {</p><p>String name ;<br />int age ;<br />String sex ;</p><p>public String getName() {<br />return name;<br />}</p><p>public void setName(String name) {<br />this.name = name;<br />}</p><p>public int getAge() {<br />return age;<br />}</p><p>public void setAge(int age) {<br />this.age = age;<br />}</p><p>public String getSex() {<br />return sex;<br />}</p><p>public void setSex(String sex) {<br />this.sex = sex;<br />}</p><p>@Override<br />public int describeContents() {<br />return 0;<br />}</p><p>/**<br /> * 將對象序號<br /> * dest 就是對象即將寫入的目的對象<br /> * flags 有關對象序號的方式的標識<br /> * 這裡要注意,寫入的順序要和在createFromParcel方法中讀出的順序完全相同。例如這裡先寫入的為name,<br /> * 那麼在createFromParcel就要先讀name<br /> */<br />@Override<br />public void writeToParcel(Parcel dest, int flags) {</p><p>dest.writeString(name);<br />dest.writeInt(age);<br />dest.writeString(sex);<br />}<br />/**<br /> * 在想要進行序號傳遞的實體類內部一定要聲明該常量。常量名只能是CREATOR,類型也必須是<br /> * Parcelable.Creator<T><br /> */<br />public static final Parcelable.Creator<Beauty> CREATOR = new Creator<Beauty>() {</p><p>/**<br /> * 建立一個要序號的實體類的數組,數組中儲存的都設定為null<br /> */<br />@Override<br />public Beauty[] newArray(int size) {<br />return new Beauty[size];<br />}</p><p>/***<br /> * 根據序號的Parcel對象,反序號為原本的實體物件<br /> * 讀出順序要和writeToParcel的寫入順序相同<br /> */<br />@Override<br />public Beauty createFromParcel(Parcel source) {<br />String name = source.readString();<br />int age = source.readInt();<br />String sex = source.readString();<br />Beauty beauty = new Beauty();<br />beauty.setName(name);<br />beauty.setAge(age);<br />beauty.setSex(sex);</p><p>return beauty;<br />}<br />};</p><p>}<br />
RemoteService.java
package cn.com.chenzheng_java.service;</p><p>import android.app.Service;<br />import android.content.Intent;<br />import android.os.IBinder;<br />import android.os.RemoteException;<br />import android.util.Log;<br />/**<br /> *<br /> * @author chenzheng_java<br /> * @description 提供服務的service<br /> *<br /> */<br />public class RemoteService extends Service {</p><p>@Override<br />public IBinder onBind(Intent intent) {<br />Log.i("通知", "執行了OnBind");<br />return new MyBinder();<br />}</p><p>private class MyBinder extends RemoteBeauty.Stub{</p><p>@Override<br />public Beauty getBeauty() throws RemoteException {</p><p>Beauty beauty = new Beauty();<br />beauty.setName("feifei");<br />beauty.setAge(21);<br />beauty.setSex("female");</p><p>return beauty;<br />}}</p><p>}<br />
ServiceActivity.java
package cn.com.chenzheng_java.service;</p><p>import android.app.Activity;<br />import android.os.Bundle;<br />/**<br /> * @description 進程之間對象資料的傳遞<br /> * @author chenzheng_java<br /> *<br /> */<br />public class ServiceActivity extends Activity {<br /> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> }<br />}
Beauty.aidl
parcelable Beauty;
RemoteBeauty.aidl
package cn.com.chenzheng_java.service;<br />import cn.com.chenzheng_java.service.Beauty;<br /> interface RemoteBeauty {</p><p>Beauty getBeauty();</p><p>}<br />
manifest.xml
<?xml version="1.0" encoding="utf-8"?><br /><manifest xmlns:android="http://schemas.android.com/apk/res/android"<br /> package="cn.com.chenzheng_java.service"<br /> android:versionCode="1"<br /> android:versionName="1.0"><br /> <uses-sdk android:minSdkVersion="8" /></p><p> <application android:icon="@drawable/icon" android:label="@string/app_name"><br /> <activity android:name=".ServiceActivity"<br /> android:label="@string/app_name"><br /> <intent-filter><br /> <action android:name="android.intent.action.MAIN" /><br /> <category android:name="android.intent.category.LAUNCHER" /><br /> </intent-filter><br /> </activity></p><p><!-- service開始 --><br /><service android:name="RemoteService"><br /><intent-filter><br /><action android:name="cn.com.chenzheng_java.remote2"/><br /></intent-filter><br /></service><br /><!-- service結束 --><br /> </application><br /></manifest>
-------------------------------------
用戶端:
ClientActivity.java
package cn.com.chenzheng_java.client;</p><p>import android.app.Activity;<br />import android.content.ComponentName;<br />import android.content.Context;<br />import android.content.Intent;<br />import android.content.ServiceConnection;<br />import android.os.Bundle;<br />import android.os.IBinder;<br />import android.os.RemoteException;<br />import android.util.Log;<br />import android.view.View;<br />import android.view.View.OnClickListener;<br />import android.widget.Button;<br />import android.widget.TextView;<br />import cn.com.chenzheng_java.service.Beauty;<br />import cn.com.chenzheng_java.service.RemoteBeauty;</p><p>public class ClientActivity extends Activity implements OnClickListener {<br />TextView textView ;<br />Button button ;<br />String actionName = "cn.com.chenzheng_java.remote2";<br />RemoteBeauty remoteBeauty;</p><p> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> textView = (TextView) findViewById(R.id.textView1);<br /> button = (Button) findViewById(R.id.button1);</p><p> button.setOnClickListener(this);<br /> }</p><p> private class MyServiceConnection implements ServiceConnection{</p><p>@Override<br />public void onServiceConnected(ComponentName name, IBinder service) {<br />Log.i("通知", "連結成功!");<br />remoteBeauty = RemoteBeauty.Stub.asInterface(service);<br />try {<br />Beauty beauty = remoteBeauty.getBeauty();<br />textView.setText("美女 姓名:"+beauty.getName()+" 年齡:"+beauty.getAge() +" 性別:"+beauty.getSex());</p><p>} catch (RemoteException e) {<br />e.printStackTrace();<br />}<br />}</p><p>@Override<br />public void onServiceDisconnected(ComponentName name) {</p><p>}</p><p> }<br /> MyServiceConnection connection = new MyServiceConnection();<br />@Override<br />public void onClick(View v) {<br />Intent intent = new Intent(actionName);<br />bindService(intent, connection, Context.BIND_AUTO_CREATE);<br />}<br />}
另外Beauty.java 以及RemoteBeauty.aidl都是從服務端系統中拷貝過來的哦。
如果你想你的service在系統開機時自啟動。可以在service的androidManifest.xml中加上這樣的配置。
<receiver android:name=".StartBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>