Android笔记三十四.Service综合实例二

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述Android笔记三十四.Service综合实例二相关的知识,希望能为你提供帮助。
综合实例2:client訪问远程Service服务 实现:通过一个button来获取远程Service的状态,并显示在两个文本框中。
【Android笔记三十四.Service综合实例二】

Android笔记三十四.Service综合实例二

文章图片
思路:如果A应用须要与B应用进行通信,调用B应用中的getName()、getAuthor()方法,B应用以Service方式向A应用提供服务。所以。我们能够将A应用看成是client,B应用为服务端,分别命名为AILDClient、AILDServer.
一、服务端应用程序1.src/com.example.aildserver/song.aidl:AILD文件     当完毕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.         } 
位置例如以下:
Android笔记三十四.Service综合实例二
Android笔记三十四.Service综合实例二

文章图片
    编写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.   }   
  30.   /*1.onBind方法 
  31.     *  service用于返回一个IBinder对象给client方便通信 
  32.   */   
  33.   @Override   
  34.   public  IBinder  onBind(Intent  arg0)  {   
  35.     return  binder;    
  36.   }   
  37.   /*2.onCreate方法 
  38.     *  当Service启动后,自己主动调用该方法,用于初始化 
  39.     *  */   
  40.   public  void  onCreate()  {   
  41.     name  =  names[current];           //给name、song赋值    
  42.     song  =  songs[current];    
  43.     System.out.println(" Service  print:name=" + name+ " song=" + song);    
  44.     super.onCreate();    
  45.   }   
  46.   /*3.onDestroy方法 
  47.     *  当訪问者调用Context.stopService方法后。调用该方法关闭Service服务 
  48.     *  */   
  49.   public  void  onDestroy()  {   
  50.     super.onDestroy();    
  51.   }   
  52.   /*4.onUnbind方法 
  53.     *  当訪问者调调用Context.unBind()方法后。调用该方法与Service解除绑定*/   
  54.   public  boolean  onUnbind(Intent  intent)  {   
  55.     return  false;    
  56.   }   
  57.      
  58. }   
注意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应用通信。
Android笔记三十四.Service综合实例二

文章图片
2.src/com.example.aildclient/MainActivity.java功能:(1)启动服务端Service服务; (2)获取返回的IBinder代理对象,并完毕与服务端程序的通信
  1. package  com.example.aildclient;    
  2.    
  3. import  com.example.aildserver.Song;    
  4.    
  5. import  android.app.Activity;    
  6. import  android.app.Service;    
  7. import  android.content.ComponentName;    
  8. import  android.content.Intent;    
  9. import  android.content.ServiceConnection;    
  10. import  android.os.Bundle;    
  11. import  android.os.IBinder;    
  12. import  android.os.RemoteException;    
  13. import  android.view.View;    
  14. import  android.view.View.OnClickListener;    
  15. import  android.widget.Button;    
  16. import  android.widget.EditText;    
  17. public  class  MainActivity  extends  Activity  {   
  18.         private  Button  getBtn;    
  19.         private  EditText  song;    
  20.         private  EditText  name;    
  21.         private  Song  binder;    
  22.         //1.创建一个ServiceConnection对象   
  23.         private  ServiceConnection  conn  =  new    ServiceConnection()   
  24.         {   
  25.     public  void  onServiceConnected(ComponentName  name,  IBinder  service)   
  26.     {   
  27.       binder  =  Song.Stub.asInterface(service);   //获取Service返回的代理IBinder对象   
  28.          
  29.     }   
  30.     public  void  onServiceDisconnected(ComponentName  name)  {   
  31.     }   
  32.         };    
  33.   protected  void  onCreate(Bundle  savedInstanceState)  {   
  34.                 super.onCreate(savedInstanceState);    
  35.                 setContentView(R.layout.main);    
  36.                 getBtn=(Button)findViewById(R.id.get);    
  37.                 song=(EditText)findViewById(R.id.song);    
  38.                 name=(EditText)findViewById(R.id.name);    
  39.         //2.指定要启动的Service   
  40.                 Intent  intent  =  new  Intent(" com.jiangdongguo.service" );    
  41.                 bindService(intent,  conn,  Service.BIND_AUTO_CREATE);    
  42.                 getBtn.setOnClickListener(new  OnClickListener(){   
  43.                      
  44.       public  void  onClick(View  arg0)   
  45.       {   
  46.         try  {   
  47.           name.setText(binder.getName());    
  48.           song.setText(binder.getSong());    
  49.         }  catch  (RemoteException  e)  {   
  50.           e.printStackTrace();    
  51.         }   
  52.       }   
  53.                 });    
  54.         }   
  55. }   
    对于远程服务调用,远程服务返回给client的对象为代理对象,client在onServiceConnected(ComponentName name, IBinder service)方法引用该对象时不能直接强转成接口类型的实例,而应该使用asInterface(IBinder iBinder)进行类型转换。
三、效果演示
Android笔记三十四.Service综合实例二

文章图片

Android笔记三十四.Service综合实例二

文章图片









    推荐阅读