天天看點

Android學習之遠端綁定調用service

http://blog.csdn.net/q1234456gggg_jkjg/article/details/8479070

遠端綁定調用service主要是用來不同程序的資訊共享。就比如伺服器和用戶端,在伺服器端設定好一個service提供方法或資訊,然後用戶端可以直接調用伺服器端service提供方法或資訊。這裡有個前提是用戶端必須有和伺服器端一份一樣的aidl,然後伺服器端在用戶端使用的系統上有注冊過(也就是安裝運作過一次),之後用戶端就可以遠端綁定調用伺服器端的service了。

具體的步驟如下:

1.首先,是伺服器的

  1)建立一個android應用工程  

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

  2)  在主aitivity所在的包裡建立個aidl檔案,這是adt會自動幫你在gen目錄下生成一個和aidl檔案同名的java檔案(這裡的aidlservice.java是下一步驟生成的,這裡可以先忽略)

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

  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)首先,建立一個工程

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

 2)接着,把伺服器端的一些檔案拷貝過來(建立com.ds.server這個包,然後往裡面複制進入如下圖的伺服器端的檔案(iaidlservice.java)

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

下面是個檔案的内容

    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視窗會顯示

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

為什麼沒有執行 log.v("aidlclientactivity","oncreate"+iservice.gettype()+" "+count);這一句,然後我再點選下bind

Android學習之遠端綁定調用service
Android學習之遠端綁定調用service

終于出現想要的結果,這裡你就會發現count變成1了,也就是之前執行過一次count+1了,這就說明了,第一次隻是綁定,傳回的 iservice是null,第二次以上才會傳回對象。

到這裡就是我之前一直錯誤的地方,是了解錯了,我之前寫的程式沒有按鈕,是直接啟動用戶端後就綁定調用service,由于沒有按鈕不能多次按,也就會造成得不到想要的結果了。這裡總算明白它的一些運作機制了,先寫到這裡,後面有什麼新發現會及時更新。

繼續閱讀