溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android service通過aidl 回調(diào)客戶端 daemon

發(fā)布時間:2020-07-12 04:38:27 來源:網(wǎng)絡(luò) 閱讀:1182 作者:yangxiaoming123 欄目:移動開發(fā)

前端時間項目運用到AIDL,關(guān)于AIDL客戶端以及AIDL服務(wù)端網(wǎng)絡(luò)上沒有一個比較完備的Demo.

而參考Demo無疑是一個比較快速的學(xué)習(xí)方法.因此,我寫了一個Demo.

供大家參考,也非常歡迎大家對其中寫的不好的地方進(jìn)行指正.

 

好了,首先簡述下基本功能:

在AIDL 客戶端三個EditText中輸入三個值,點擊提交按鈕,將這三個值傳入到AIDL服務(wù)端進(jìn)行處理.

服務(wù)端處理后會執(zhí)行客戶端的回調(diào)函數(shù):在AIDL客戶端界面進(jìn)行刷新,并顯示一個toast.

 

接下來看看代碼結(jié)構(gòu):

Android  service通過aidl  回調(diào)客戶端 daemon

 

需要注意的是,兩個工程中com.harlan.demo.aidl包內(nèi)部的文件必須保持一致.

 

(1)HarlanInfo.java:這是包中唯一的一個java文件,是一個數(shù)據(jù)結(jié)構(gòu),該類實現(xiàn)了Parcelable接口

[java] view plaincopyprint?

  1. package com.harlan.demo.aidl;  

  2.   

  3. import android.os.Parcel;  

  4. import android.os.Parcelable;  

  5.   

  6. /** 

  7.  *  

  8.  * <一句話功能簡述> 

  9.  * Parcelable是Android特有的功能,效率比實現(xiàn)Serializable接口高 

  10.  *  

  11.  * @author  Administrator 

  12.  * @version  [版本號, 2012-12-10] 

  13.  * @see  [相關(guān)類/方法] 

  14.  * @since  [產(chǎn)品/模塊版本] 

  15.  */  

  16. public class HarlanInfo implements Parcelable  

  17. {  

  18.     private String name;  

  19.       

  20.     private int age;  

  21.       

  22.     private String place;  

  23.   

  24.     public String getName()  

  25.     {  

  26.         return name;  

  27.     }  

  28.   

  29.     public void setName(String name)  

  30.     {  

  31.         this.name = name;  

  32.     }  

  33.   

  34.     public int getAge()  

  35.     {  

  36.         return age;  

  37.     }  

  38.   

  39.     public void setAge(int age)  

  40.     {  

  41.         this.age = age;  

  42.     }  

  43.   

  44.     public String getPlace()  

  45.     {  

  46.         return place;  

  47.     }  

  48.   

  49.     public void setPlace(String place)  

  50.     {  

  51.         this.place = place;  

  52.     }  

  53.       

  54.     /** 

  55.      * <默認(rèn)構(gòu)造函數(shù)> 

  56.      */  

  57.     public HarlanInfo()  

  58.     {  

  59.           

  60.     }  

  61.       

  62.     /** 

  63.      * <默認(rèn)構(gòu)造函數(shù)> 

  64.      */  

  65.     public HarlanInfo(Parcel in)  

  66.     {  

  67.         //注意順序  

  68.          name = in.readString();  

  69.         age = in.readInt();  

  70.         place = in.readString();  

  71.     }  

  72.       

  73.     /** 

  74.      * seems meaningless 

  75.      * return 0; 

  76.      */  

  77.     @Override  

  78.     public int describeContents()  

  79.     {  

  80.         return 0;  

  81.     }  

  82.   

  83.     /** 

  84.      * 將對象序列化為一個Parcel對象 

  85.      *  可以將Parcel看成是一個流,通過writeToParcel把對象寫到流里面, 

  86.      *  再通過createFromParcel從流里讀取對象 

  87.      *  注意:寫的順序和讀的順序必須一致。  

  88.      */  

  89.     @Override  

  90.     public void writeToParcel(Parcel dest, int flags)  

  91.     {  

  92.         dest.writeString(name);  

  93.         dest.writeInt(age);  

  94.         dest.writeString(place);  

  95.     }  

  96.       

  97.     /** 

  98.      * 實例化靜態(tài)內(nèi)部對象CREATOR實現(xiàn)接口Parcelable.Creator 

  99.      * public static final一個都不能少,內(nèi)部對象CREATOR的名稱也不能改變,必須全部大寫 

  100.      */  

  101.     public static final Parcelable.Creator<HarlanInfo> CREATOR = new Creator<HarlanInfo>(){  

  102.   

  103.       //將Parcel對象反序列化為HarlanInfo     

  104.         @Override  

  105.         public HarlanInfo createFromParcel(Parcel source)  

  106.         {  

  107.             HarlanInfo hlInfo = new HarlanInfo(source);  

  108.             return hlInfo;  

  109.         }  

  110.   

  111.         @Override  

  112.         public HarlanInfo[] newArray(int size)  

  113.         {  

  114.             return new HarlanInfo[size];  

  115.         }  

  116.           

  117.     };  

  118.       

  119. }  

 

(2)HarlanInfo.aidl :協(xié)同HarlanInfo.java文件"作戰(zhàn)",缺一不可.

[java] view plaincopyprint?

  1. package com.harlan.demo.aidl;  

  2.   

  3. parcelable HarlanInfo;  

 

(3)ICallBack.aidl:
這是客戶端回調(diào)方法的接口,在客戶端實現(xiàn)其具體方法,在服務(wù)端調(diào)用執(zhí)行.

[java] view plaincopyprint?

  1. package com.harlan.demo.aidl;  

  2. interface ICallBack{  

  3.     /** 

  4.     *callback of AIDLClient 

  5.     *handle by server 

  6.     **/  

  7.     void handleByServer(String param);  

  8. }  

 

(4)ExecuteService.aidl:

這是從服務(wù)端獲取數(shù)據(jù)方法的接口,在服務(wù)端實現(xiàn)其具體方法,在客戶端調(diào)用執(zhí)行.

參數(shù)info是由用戶輸入的數(shù)據(jù)構(gòu)成的,同時傳遞的還要客戶端回調(diào)方法的句柄,從而服務(wù)端可以調(diào)用客戶端的回調(diào)方法.

該方法返回一個HarlanInfo的數(shù)據(jù)類型,客戶端獲得此數(shù)據(jù),在界面上進(jìn)行相應(yīng)的顯示.

[java] view plaincopyprint?

  1. package com.harlan.demo.aidl;  

  2. import com.harlan.demo.aidl.HarlanInfo;  

  3. import com.harlan.demo.aidl.ICallBack;  

  4. interface ExecuteServiceAIDL  

  5. {  

  6.     /** 

  7.      *get info from server and  

  8.      *Transfer a callback methods handle; 

  9.      *if occur error ,will be return null 

  10.      *對于非基本數(shù)據(jù)類型和String和CharSequence類型,要加上方向指示 

  11.      *包括in、out和inout,in表示由客戶端設(shè)置,out表示由服務(wù)端設(shè)置,inout是兩者均可設(shè)置。 

  12.      */  

  13.     HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);  

  14. }  


好了,現(xiàn)在對com.harlan.demo.aidl包已經(jīng)大致了解,build一下project,發(fā)現(xiàn)gen文件夾下面多出來一個包:

Android  service通過aidl  回調(diào)客戶端 daemon
 包中文件可以隨便看看,不看也沒事.因為你只要在客戶端服務(wù)端相應(yīng)的位置實現(xiàn)對應(yīng)的接口就可以了.

先來看看服務(wù)端,因為服務(wù)端相對簡單些,不需要界面什么的,只是一個Service.

上代碼:

[java] view plaincopyprint?

  1. package com.harlan.demo.service;  

  2.   

  3. import android.app.Service;  

  4. import android.content.Intent;  

  5. import android.os.IBinder;  

  6. import android.os.RemoteException;  

  7. import android.util.Log;  

  8.   

  9. import com.harlan.demo.aidl.ExecuteServiceAIDL;  

  10. import com.harlan.demo.aidl.HarlanInfo;  

  11. import com.harlan.demo.aidl.ICallBack;  

  12.   

  13. public class AIDLService extends Service  

  14. {  

  15.     public static final String TAG = "AIDLService";  

  16.       

  17.     private ICallBack mCallBack;  

  18.       

  19.     /** 

  20.      * 綁定服務(wù) 

  21.      */  

  22.     @Override  

  23.     public IBinder onBind(Intent intent)  

  24.     {  

  25.         // TODO Auto-generated method stub  

  26.         return mBinder;  

  27.     }  

  28.       

  29.     /** 

  30.      * 創(chuàng)建服務(wù) 

  31.      */  

  32.     @Override  

  33.     public void onCreate()  

  34.     {  

  35.         super.onCreate();  

  36.     }  

  37.   

  38.     /** 

  39.      * 銷毀服務(wù) 

  40.      */  

  41.     @Override  

  42.     public void onDestroy()  

  43.     {  

  44.         super.onDestroy();  

  45.     }  

  46.   

  47.     /** 

  48.      * 啟動服務(wù) 

  49.      */  

  50.     @Override  

  51.     public void onStart(Intent intent, int startId)  

  52.     {  

  53.         super.onStart(intent, startId);  

  54.     }  

  55.   

  56.     /** 

  57.      * 解綁服務(wù) 

  58.      */  

  59.     @Override  

  60.     public boolean onUnbind(Intent intent)  

  61.     {  

  62.         mCallBack = null;  

  63.         return super.onUnbind(intent);  

  64.     }  

  65.       

  66.     ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()  

  67.     {  

  68.        //這里實現(xiàn)了getServiceHarlanInfo接口  

  69.         @Override  

  70.         public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)  

  71.             throws RemoteException  

  72.         {  

  73.             Log.d(TAG,"getServerHarlanInfo");  

  74.             mCallBack = icallback;  

  75.             mCallBack.handleByServer("The msg is from server");  

  76.             HarlanInfo newInfo = new HarlanInfo();  

  77.             newInfo.setName(info.getName().toLowerCase());  

  78.             newInfo.setAge(info.getAge() + 10);  

  79.             newInfo.setPlace("Home");  

  80.             return newInfo;  

  81.         }  

  82.     };  

  83.       

  84. }  

一目了然,服務(wù)端主要的功能就是實現(xiàn)了aidl中的getServerHarlanInfo(HarlanInfo info, ICallBack icallback)接口.返回了一個mBinder供客戶端調(diào)用.

寫好了服務(wù),還得在Manifest文件里面配置一下:

[java] view plaincopyprint?

  1. <service   

  2.            android:name=".AIDLService">  

  3.            <intent-filter>  

  4.                <action android:name="com.harlan.demo.aidl.service"/>  

  5.            </intent-filter>  

  6. lt;/service>  

 

服務(wù)端寫好了,就來客戶端的了.客戶端主要是一個activity,界面相對簡單,如圖所示:

Android  service通過aidl  回調(diào)客戶端 daemon

界面布局相對簡單,就不貼代碼了.

 

下面貼ClientActivity的代碼:

[java] view plaincopyprint?

  1. package com.harlan.demo.activity;  

  2.   

  3. import android.app.Activity;  

  4. import android.content.ComponentName;  

  5. import android.content.Intent;  

  6. import android.content.ServiceConnection;  

  7. import android.os.Bundle;  

  8. import android.os.IBinder;  

  9. import android.os.RemoteException;  

  10. import android.util.Log;  

  11. import android.view.View;  

  12. import android.widget.Button;  

  13. import android.widget.EditText;  

  14. import android.widget.Toast;  

  15.   

  16. import com.harlan.demo.aidl.ExecuteServiceAIDL;  

  17. import com.harlan.demo.aidl.HarlanInfo;  

  18. import com.harlan.demo.aidl.ICallBack;  

  19.   

  20. public class ClientActivity extends Activity  

  21. {  

  22.     public static final String TAG = "ClientActivity";  

  23.       

  24.     private static final String BIND_ACTION = "com.harlan.demo.aidl.service";  

  25.       

  26.     private EditText mEditTextName;  

  27.       

  28.     private EditText mEditTextAge;  

  29.       

  30.     private EditText mEditTextPlace;  

  31.       

  32.     private Button mButtonCommit;  

  33.       

  34.     private ExecuteServiceAIDL executeService;  

  35.       

  36.     @Override  

  37.     protected void onCreate(Bundle savedInstanceState)  

  38.     {  

  39.         super.onCreate(savedInstanceState);  

  40.         setContentView(R.layout.activity_client);  

  41.         getView();  

  42.     //用戶點擊提交按鈕,將數(shù)據(jù)傳至服務(wù)端進(jìn)行處理    

  43.          mButtonCommit.setOnClickListener(new View.OnClickListener()  

  44.         {  

  45.               

  46.             @Override  

  47.             public void onClick(View v)  

  48.             {  

  49.         //綁定服務(wù)  

  50.                 getServiceConnect();               

  51.             }  

  52.         });  

  53.     }  

  54.           

  55.     private void getView()  

  56.     {  

  57.         mEditTextName = (EditText)findViewById(R.id.editText_name);  

  58.         mEditTextAge = (EditText)findViewById(R.id.editText_age);  

  59.         mEditTextPlace = (EditText)findViewById(R.id.editText_place);  

  60.         mButtonCommit = (Button)findViewById(R.id.button_commit);  

  61.     }  

  62.       

  63.     private void getServiceConnect()  

  64.     {  

  65.         Intent it = new Intent();  

  66.         it.setAction(BIND_ACTION);  

  67.         startService(it);  

  68.         bindService(it, mserviceConnection, BIND_AUTO_CREATE);  

  69.     }  

  70.       

  71.     ServiceConnection mserviceConnection = new ServiceConnection()  

  72.     {  

  73.           

  74.         @Override  

  75.         public void onServiceDisconnected(ComponentName name)  

  76.         {  

  77.             Log.d(TAG, "onServiceDisconnected");             

  78.         }  

  79.           

  80.         @Override  

  81.         public void onServiceConnected(ComponentName name, IBinder service)  

  82.         {  

  83.             Log.d(TAG, "onServiceConnected");  

  84.             //獲取服務(wù)端傳過來的IBinder對象,通過該對象調(diào)用服務(wù)端的方法  

  85.               executeService = ExecuteServiceAIDL.Stub.asInterface(service);  

  86.             if (executeService != null)  

  87.             {  

  88.                 handlerInfo();  

  89.             }  

  90.         }  

  91.     };  

  92.       

  93.     private void handlerInfo()  

  94.     {  

  95.         String mName;  

  96.         int mAge;  

  97.         String mPlace;  

  98.         if (mEditTextName.getText().toString().equals(""))  

  99.         {  

  100.             mEditTextName.setText("Harlan");  

  101.             mName = "Harlan";  

  102.         }  

  103.         else  

  104.         {  

  105.             mName = mEditTextName.getText().toString();  

  106.         }  

  107.         if (mEditTextAge.getText().toString().equals(""))  

  108.         {  

  109.             mAge = 22;  

  110.         }  

  111.         else  

  112.         {  

  113.             mAge = Integer.parseInt(mEditTextAge.getText().toString());  

  114.         }  

  115.         if (mEditTextPlace.getText().toString().equals(""))  

  116.         {  

  117.             mPlace = "Nanjing";  

  118.         }  

  119.         else  

  120.         {  

  121.             mPlace = mEditTextPlace.getText().toString();  

  122.         }  

  123.         HarlanInfo mInfo = new HarlanInfo();  

  124.         mInfo.setName(mName);  

  125.         mInfo.setAge(mAge);  

  126.         mInfo.setPlace(mPlace);  

  127.         try  

  128.         {  

  129.             HarlanInfo serverInfo = new HarlanInfo();  

  130.        //調(diào)用服務(wù)端的方法  

  131.               serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);  

  132.             //更新界面  

  133.               mEditTextName.setText(serverInfo.getName());  

  134.             mEditTextAge.setText(String.valueOf(serverInfo.getAge()));  

  135.             mEditTextPlace.setText(serverInfo.getPlace());  

  136.             unbindService(mserviceConnection);  

  137.         }  

  138.         catch (RemoteException e)  

  139.         {  

  140.             e.printStackTrace();  

  141.         }  

  142.     }  

  143.     ICallBack.Stub mCallBack = new ICallBack.Stub()  

  144.     {  

  145.        //客戶端回調(diào)方法的具體實現(xiàn)  

  146.         @Override  

  147.         public void handleByServer(String param)  

  148.             throws RemoteException  

  149.         {  

  150.             Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();            

  151.         }  

  152.     };  

  153.      

  154. }  

服務(wù)端調(diào)用客戶端回調(diào)方法,在界面上顯示一個toast.客戶端根據(jù)服務(wù)端傳回來的數(shù)據(jù),刷新界面. 

最后運行結(jié)果如圖所示:

Android  service通過aidl  回調(diào)客戶端 daemon

 

 

具體的Demo已經(jīng)上傳至CSDN,下載地址:http://download.csdn.net/detail/singleton1900/4928804


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI