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


    综合实例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.  }  
    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应用通信。
    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)进行类型转换。

    三、效果演示


  • 相关阅读:
    【计蒜客】贝壳找房户外拓展(中等)扫描线+线段树
    【CodeForces】925 C.Big Secret 异或
    【LibreOJ】#6392. 「THUPC2018」密码学第三次小作业 / Rsa 扩展欧几里得算法
    【LibreOJ】#6395. 「THUPC2018」城市地铁规划 / City 背包DP+Prufer序
    【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
    【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas
    【计蒜客】百度科学家(困难)
    【BZOJ】2115: [Wc2011] Xor
    【GDOI2018】所有题目和解题报告
    【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7040236.html
Copyright © 2020-2023  润新知