1. 程式人生 > >Android筆記三十四.Service綜合實例二

Android筆記三十四.Service綜合實例二

com err out 生成 lds fcm con .so ron

綜合實例2:client訪問遠程Service服務 實現:通過一個button來獲取遠程Service的狀態,並顯示在兩個文本框中。

技術分享 思路:如果A應用須要與B應用進行通信,調用B應用中的getName()、getAuthor()方法,B應用以Service方式向A應用提供服務。所以。我們能夠將A應用看成是client,B應用為服務端,分別命名為AILDClient、AILDServer.
一、服務端應用程序 1.src/com.example.aildserver/song.aidlAILD文件 當完畢aidl文件創建後,選擇保存,eclipse會自己主動在項目的gen文件夾中同步生成Song.java接口文件。接口文件裏生成一個Stub抽象類,裏面包含aidl定義的方法。還包含一些其他

輔助性的方法,如geName()、getSong()方法,我們能夠通過這兩個方法實現client讀寫Service服務端數據
  1. package com.example.aildserver;
  2. interface Song
  3. {
  4. String getName();
  5. String getSong();
  6. }
位置例如以下: 技術分享
技術分享 編寫Aidl文件時,須要註意: 1.接口名和aidl文件名稱同樣; 2.接口和方法前不用加訪問權限修飾符public,private等,也不能用final,static; 3.Aidl默認支持的類型包話java基本類型(int、long、boolean等)和(String、List、Map、CharSequence),使用這些類型時不須要import聲明。對於List和Map中的元素類型必須是Aidl支持的類型。假設使用自己定義類型作為參數或返回值。自己定義類型必須實現Parcelable接口。 4.自己定義類型和AIDL生成的其他接口類型在aidl描寫敘述文件裏,應該顯式import,即便在該類和定義的包在同一個包中。
5.在aidl文件裏全部非Java基本類型參數必須加上in、out、inout標記,以指明參數是輸入參數、輸出參數還是輸入輸出參數。 6.Java原始類型默認的標記為in,不能為其他標記。

2.src/com.example.aildserver/MyService.java 功能:Service子類。完畢Service服務 開發核心步驟: (1)重寫Service的onBind()方法(用於返回一個IBinder對象)、onCreate()方法、onDestroy() 方法、onUnbind()方法; (2)定義一個Stub的子類。該內部類實現了IBinder、Song兩個接口。該子類對象將作為遠程Service的onBind()方法返回IBinder對象的代理傳給client的ServiceConnection的onServiceConnected方法的第二個參數。

  1. package com.example.aildserver;
  2. import com.example.aildserver.Song.Stub;
  3. import android.app.Service;
  4. import android.content.Intent;
  5. import android.os.Binder;
  6. import android.os.IBinder;
  7. import android.os.RemoteException;
  8. public class MyService extends Service {
  9. private String[] names = new String[] {"林俊傑","蔡依林","鄧紫棋"};
  10. private String[] songs = new String[] {"可惜沒假設","第三人稱","多遠都要在一起"};
  11. private String name,song;
  12. private int current=1; //當前位置
  13. private MyBinder binder = new MyBinder(); //實例化一個IBinder對象
  14. /*0.Stub內部類
  15. * 該內部類實現了IBinder、Song兩個接口,這個Stub類將會作為遠程Service的回調類。*/
  16. public class MyBinder extends Stub
  17. {
  18. //a.client回調該方法獲取歌手名
  19. public String getName() throws RemoteException
  20. {
  21. return name;
  22. }
  23. //b.client回調該方法獲取歌曲
  24. public String getSong() throws RemoteException
  25. {
  26. return song;
  27. }
  28. }
  29. /*1.onBind方法
  30. * service用於返回一個IBinder對象給client方便通信
  31. */
  32. @Override
  33. public IBinder onBind(Intent arg0) {
  34. return binder;
  35. }
  36. /*2.onCreate方法
  37. * 當Service啟動後,自己主動調用該方法,用於初始化
  38. * */
  39. public void onCreate() {
  40. name = names[current]; //給name、song賦值
  41. song = songs[current];
  42. System.out.println("Service print:name="+name+"song="+song);
  43. super.onCreate();
  44. }
  45. /*3.onDestroy方法
  46. * 當訪問者調用Context.stopService方法後。調用該方法關閉Service服務
  47. * */
  48. public void onDestroy() {
  49. super.onDestroy();
  50. }
  51. /*4.onUnbind方法
  52. * 當訪問者調調用Context.unBind()方法後。調用該方法與Service解除綁定*/
  53. public boolean onUnbind(Intent intent) {
  54. return false;
  55. }
  56. }
註意1:client訪問Service時。Android並非直接返回Service對象給client。Service僅僅是將一個回調對象(IBinder對象)通過onBind()方法回調給client。

註意2:與綁定本地Service不同的是,本地Service的onBind()方法會直接把IBinder對象本身傳給client的ServiceConnection的onServiceConnected方法的第二個參數。

但遠程Service的onBind()方法僅僅是將IBinder對象的代理傳給client的ServiceConnection的onServiceConnected方法的第二個參數。

當client獲取了遠程的Service的IBinder對象的代理之後,接下來可通過該IBinder對象去回調遠程Service的屬性或方法。 3.AndroidManifest.xml 功能:配置Service組件,並指定其action屬性(方便其它應用程序啟動該Service服務)

  1. <application
  2. ........
  3. <!-- 配置service -->
  4. <service android:name=".MyService">
  5. <intent-filter>
  6. <action android:name="com.jiangdongguo.service"/>
  7. </intent-filter>
  8. </service>
  9. </application>

二、client應用程序
1.拷貝服務端.aidl文件到client 把AIDLService應用中aidl文件所在package連同aidl文件一起復制到clientAIDLClient應用,eclipse會自己主動在A應用的gen文件夾中為aidl文件同步生成Song.java接口文件,接下來就能夠在AIDLClient應用中實現與AIDLService應用通信。 技術分享 2.src/com.example.aildclient/MainActivity.java 功能:(1)啟動服務端Service服務;(2)獲取返回的IBinder代理對象,並完畢與服務端程序的通信
  1. package com.example.aildclient;
  2. import com.example.aildserver.Song;
  3. import android.app.Activity;
  4. import android.app.Service;
  5. import android.content.ComponentName;
  6. import android.content.Intent;
  7. import android.content.ServiceConnection;
  8. import android.os.Bundle;
  9. import android.os.IBinder;
  10. import android.os.RemoteException;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.EditText;
  15. public class MainActivity extends Activity {
  16. private Button getBtn;
  17. private EditText song;
  18. private EditText name;
  19. private Song binder;
  20. //1.創建一個ServiceConnection對象
  21. private ServiceConnection conn = new ServiceConnection()
  22. {
  23. public void onServiceConnected(ComponentName name, IBinder service)
  24. {
  25. binder = Song.Stub.asInterface(service); //獲取Service返回的代理IBinder對象
  26. }
  27. public void onServiceDisconnected(ComponentName name) {
  28. }
  29. };
  30. protected void onCreate(Bundle savedInstanceState) {
  31. super.onCreate(savedInstanceState);
  32. setContentView(R.layout.main);
  33. getBtn=(Button)findViewById(R.id.get);
  34. song=(EditText)findViewById(R.id.song);
  35. name=(EditText)findViewById(R.id.name);
  36. //2.指定要啟動的Service
  37. Intent intent = new Intent("com.jiangdongguo.service");
  38. bindService(intent, conn, Service.BIND_AUTO_CREATE);
  39. getBtn.setOnClickListener(new OnClickListener(){
  40. public void onClick(View arg0)
  41. {
  42. try {
  43. name.setText(binder.getName());
  44. song.setText(binder.getSong());
  45. } catch (RemoteException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. });
  50. }
  51. }
對於遠程服務調用,遠程服務返回給client的對象為代理對象,client在onServiceConnected(ComponentName name, IBinder service)方法引用該對象時不能直接強轉成接口類型的實例,而應該使用asInterface(IBinder iBinder)進行類型轉換。

三、效果演示 技術分享
技術分享

Android筆記三十四.Service綜合實例二