http://blog.csdn.net/q1234456gggg_jkjg/article/details/8479070
遠端綁定調用service主要是用來不同程序的資訊共享。就比如伺服器和用戶端,在伺服器端設定好一個service提供方法或資訊,然後用戶端可以直接調用伺服器端service提供方法或資訊。這裡有個前提是用戶端必須有和伺服器端一份一樣的aidl,然後伺服器端在用戶端使用的系統上有注冊過(也就是安裝運作過一次),之後用戶端就可以遠端綁定調用伺服器端的service了。
具體的步驟如下:
1.首先,是伺服器的
1)建立一個android應用工程
2) 在主aitivity所在的包裡建立個aidl檔案,這是adt會自動幫你在gen目錄下生成一個和aidl檔案同名的java檔案(這裡的aidlservice.java是下一步驟生成的,這裡可以先忽略)
3)如上圖所示,建立一個用來使用service的類(aidlservice.java)
具體每個檔案的代碼如下:
aidlserveractivity.java
[java] view
plaincopy
package com.ds.server;
import android.app.activity;
import android.content.intent;
import android.os.bundle;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.toast;
public class aidlserveractivity extends activity {
/** called when the activity is first created. */
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.main);
button bt = (button) findviewbyid(r.id.bt);
bt.setonclicklistener(new onclicklistener() {
@override
public void onclick(view v) {
// todo auto-generated method stub
intent service = new intent(aidlserveractivity.this,
aidlservice.class);
startservice(service);
toast.maketext(aidlserveractivity.this, "service started",
toast.length_long).show();
}
});
}
}
iaidlservice.aidl
interface iaidlservice {
int gettype();
}
aidlservice.java
import android.app.service;
import android.os.ibinder;
import android.os.remoteexception;
import android.util.log;
public class aidlservice extends service {
private boolean unrunnable;
private int count;
private class mybinder extends iaidlservice.stub {
@override
public int gettype() throws remoteexception {
// todo auto-generated method stub
return 100;
}
private void log(string str) {
log.d("aidlservice", "------ " + str + "------");
public void oncreate() {
super.oncreate();
/*
new thread(new runnable(){
@override
public void run(){
while(!unrunnable){
try{
thread.sleep(1000);
}catch(interruptedexception e){
}
count++;
log.v("aidlservice","count:"+count);
}
}
}).start();
*/
log.v("remotecountservice","oncreate");
log("service create");
/*
@override
public void onstart(intent intent, int startid) {
log("service start id=" + startid);
}
*/
public ibinder onbind(intent t) {
log("service on bind");
return new mybinder();
public void ondestroy() {
log("service on destroy");
unrunnable=true;
super.ondestroy();
/*
public boolean onunbind(intent intent) {
log("service on unbind");
return super.onunbind(intent);
public void onrebind(intent intent) {
log("service on rebind");
super.onrebind(intent);
*/
布局檔案androidmanifest.xml
[html] view
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ds.server"
android:versioncode="1"
android:versionname="1.0" >
<uses-sdk android:minsdkversion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".aidlserveractivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.main" />
<category android:name="android.intent.category.launcher" />
</intent-filter>
</activity>
<service
android:name=".aidlservice"
android:enabled="true"
android:process=":remote" >
<!-- aidl完整路徑名。必須指明,用戶端能夠通過aidl類名查找到它的實作類 -->
<action android:name="com.ds.server.iaidlservice" />
<category android:name="android.intent.category.default" />
</service>
</application>
</manifest>
這裡,伺服器端的工作做好了,接下來是用戶端的工作。
2.接着,是用戶端的:
1)首先,建立一個工程
2)接着,把伺服器端的一些檔案拷貝過來(建立com.ds.server這個包,然後往裡面複制進入如下圖的伺服器端的檔案(iaidlservice.java)
下面是個檔案的内容
aidlclientactivity.java
package com.ds.client;
import com.ds.server.iaidlservice;
import android.content.componentname;
import android.content.serviceconnection;
import android.widget.textview;
public class aidlclientactivity extends activity {
iaidlservice iservice;
int count;
private serviceconnection connection = new serviceconnection() {
public void onserviceconnected(componentname name, ibinder service) {
// 浠庤繙绋媠ervice涓幏寰桝idl瀹炰緥鍖栧璞�
iservice = iaidlservice.stub.asinterface(service);
log.i("client","bind success:" + iservice);
}
public void onservicedisconnected(componentname name) {
iservice = null;
log.i("client","onservicedisconnected");
};
public void oncreate(bundle savedinstancestate) {
final textview tv = (textview) findviewbyid(r.id.tv);
public void onclick(view arg0) {
intent service = new intent(iaidlservice.class.getname());
bindservice(service, connection, bind_auto_create);
if (iservice != null) {
try {
log.v("aidlclientactivity","oncreate"+iservice.gettype()+" "+count);
} catch (remoteexception e) {
e.printstacktrace();
}
}
else{
count++;
}
});
androidmanifest.xml
package="com.ds.client"
android:name=".aidlclientactivity"
這樣用戶端的工作也算完了,但這裡我還想說下一個問題。
你可能會看到在用戶端的activity檔案裡,有個count的變量,覺得是多餘的,但這是為了說明下面這個問題的需要。
最開始的count是0,然後我運作用戶端後,滑鼠左擊bind按鈕,會發現logcat的verbose視窗會顯示
為什麼沒有執行 log.v("aidlclientactivity","oncreate"+iservice.gettype()+" "+count);這一句,然後我再點選下bind
終于出現想要的結果,這裡你就會發現count變成1了,也就是之前執行過一次count+1了,這就說明了,第一次隻是綁定,傳回的 iservice是null,第二次以上才會傳回對象。
到這裡就是我之前一直錯誤的地方,是了解錯了,我之前寫的程式沒有按鈕,是直接啟動用戶端後就綁定調用service,由于沒有按鈕不能多次按,也就會造成得不到想要的結果了。這裡總算明白它的一些運作機制了,先寫到這裡,後面有什麼新發現會及時更新。