• Android开发之Service的远程调用


       在Andorid平台中,各个组件运行在自己的进程中,他们之间是不能相互访问的,但是在程序之间是不可避免的要传递一些对象,在进程之间相互通信。为了实现进程之间的相互通信,Andorid采用了一种轻量级的实现方式RPC(Remote Procedure Call 远程进程调用)来完成进程之间的通信,并且Android通过接口定义语言(Andorid Interface Definition Language ,AIDL)来生成两个进程之间相互访问的代码,例如,你在Activity里的代码需要访问Service中的一个方法,那么就可以通过这种方式来实现了。

       AIDL是Android的一种接口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象。

       AIDL RPC机制是通过接口来实现的,类似Windows中的COM或者Corba,但他是轻量级的,客户端和被调用实现之间是通过代理模式实现的,代理类和被代理类实现同一个接口Ibinder接口。

    下面是实现Activity访问Service例子的步骤:

    一.创建.aidl文件

        AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。重要的是必须导入导入除了内建类型(例如:int,boolean等)外的任何其他类型,哪怕是这些类型是在与接口相同的包中。具体的要求如下:

    • JAVA基本数据类型不需要导入
    • String,List,MapCharSequence不需要导入

    使用Eclipse的ADT插件创建一个BookInfo.aidl文件,该文件有4个方法:

    setName(String name)设置图书的书名,setPrice(int price)设置图书的价格,setPublish(String pname)设置图书的出版社和String display()显示图书的信息.

    BookInfo.aidl文件

    1. package com.android.aidl;  
    2.  
    3. //BookInfo接口  
    4. interface BookInfo{  
    5.       
    6.     void setName(String name);  
    7.     void setPrice(int price);  
    8.     void ssetPublish(String pname);  
    9.     //显示图书的信息  
    10.     String display();  

    创建好BookInfo.aidl文件,系统会自动在gen目录下生成Java接口文件BookInfo.java

    二.实现AIDL文件生成的JAVA接口

        AIDL会生成一个和.aidl文件同名的JAVA接口文件,该接口中有一个静态抽象内部类Stub,该类中声明了AIDL文件中定义的所有方法,其中有一个重要的方法是asInterface(),该方法通过代理模式返回JAVA接口的实现我们可以定义一个实现类,BookImpl,该类继承Stub类,实现我们定义的4个方法

    1. package com.android.aidl;  
    2. import android.os.RemoteException;  
    3.  
    4. public class BookInfoImpl extends BookInfo.Stub {  
    5.     //声明三个个变量  
    6.     private int price;  
    7.     private String name,pname;  
    8.     //显示书名,价格,出版社  
    9.     public String display() throws RemoteException{  
    10.         return "书名:"+name+";价格:"+price+";出版社:"+price;  
    11.     }  
    12.     @Override 
    13.     //设置书名  
    14.     public void setName(String name) throws RemoteException {  
    15.         // TODO Auto  
    16.         this.name= name;  
    17.     }  
    18.  
    19.     @Override 
    20.     //设置价格  
    21.     public void setPrice(int price) throws RemoteException {  
    22.         // TODO Auto-generated method stub  
    23.         this.price = price;  
    24.     }  
    25.     @Override 
    26.     //设置出版社  
    27.     public void setPublish(String pname) throws RemoteException {  
    28.         // TODO Auto  
    29.         this.pname= pname;  
    30.     }     
    31. }  

    三.向客户端暴露接口

    现在已经实现了BookInfo接口,接下来要将该接口暴露给客户端调用。一般通过定义一个Service来实现,在Service的onBind()方法中返回该接口,当我们绑定该接口时调用该方法。

    1. package com.android.aidl;  
    2.  
    3. import com.android.aidl.BookInfo.Stub;  
    4. import android.app.Service;  
    5. import android.content.Intent;  
    6. import android.os.IBinder;  
    7.  
    8. public class RemoteService extends Service {  
    9.     //声明BookInfo接口  
    10.     private Stub bookifo = new BookInfoImpl();  
    11.     public IBinder onBind(Intent intent){  
    12.         return bookifo;  
    13.     }  

    四.在客户端调用

    定义一个Activity来绑定远程Service,获得BookInfo接口,通过RPC机制调用接口中的方法。

    1. package com.android.aidl;  
    2.  
    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.Toast;  
    15.  
    16. public class MainActivity extends Activity {  
    17.     // 声明IPerson接口  
    18.     private BookInfo bookInfo;  
    19.     // 声明 Button  
    20.     private Button btn;  
    21.     // 实例化ServiceConnection  
    22.     private ServiceConnection conn = new ServiceConnection() {  
    23.         @Override 
    24.         synchronized public void onServiceConnected(ComponentName name, IBinder service) {  
    25.             // 获得IPerson接口  
    26.             bookInfo = BookInfo.Stub.asInterface(service);  
    27.             if (bookInfo != null)  
    28.                 try {  
    29.                     // RPC 方法调用  
    30.                     bookInfo.setName("Google Android SDK开发范例大全");  
    31.                     bookInfo.setPrice(55);  
    32.                     bookInfo.setPublish("人民邮电出版社");  
    33.                     String msg = bookInfo.display();  
    34.                     // 显示方法调用返回值  
    35.                     Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG)  
    36.                             .show();  
    37.                 } catch (RemoteException e) {  
    38.                     e.printStackTrace();  
    39.                 }  
    40.         }  
    41.  
    42.         @Override 
    43.         public void onServiceDisconnected(ComponentName name) {  
    44.  
    45.         }  
    46.     };  
    47.  
    48.     @Override 
    49.     public void onCreate(Bundle savedInstanceState) {  
    50.         super.onCreate(savedInstanceState);  
    51.         // 设置当前视图布局  
    52.         setContentView(R.layout.main);  
    53.         // 实例化Button  
    54.         btn = (Button) findViewById(R.id.Button1);  
    55.         //为Button添加单击事件监听器  
    56.         btn.setOnClickListener(new OnClickListener() {  
    57.             @Override 
    58.             public void onClick(View v) {  
    59.                 // 实例化Intent  
    60.                 Intent intent = new Intent();  
    61.                 // 设置Intent Action 属性  
    62.                 intent.setAction("com.android.aidl.action.MY_REMOTE_SERVICE");  
    63.                 // 绑定服务  
    64.                 bindService(intent, conn, Service.BIND_AUTO_CREATE);  
    65.             }  
    66.         });  
    67.     }  

    五.main.xml和AndroidManifest.xml文件

    main.xml

    1. <?xml version="1.0" encoding="utf-8"?> 
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    3.     android:orientation="vertical" 
    4.     android:layout_width="fill_parent" 
    5.     android:layout_height="fill_parent" 
    6.     > 
    7.     <Button   
    8.         android:text="远程调用Service"   
    9.         android:id="@+id/Button1"   
    10.         android:layout_width="wrap_content"   
    11.         android:layout_height="wrap_content" 
    12.         /> 
    13. </LinearLayout> 

    在AndroidManifest.xml文件16~20声明Service

    1. <?xml version="1.0" encoding="utf-8"?> 
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    3.       package="com.android.aidl" 
    4.       android:versionCode="1" 
    5.       android:versionName="1.0"> 
    6.     <uses-sdk android:minSdkVersion="10" /> 
    7.  
    8.     <application android:icon="@drawable/icon" android:label="@string/app_name"> 
    9.         <activity android:name=".MainActivity" 
    10.                   android:label="@string/app_name"> 
    11.             <intent-filter> 
    12.                 <action android:name="android.intent.action.MAIN" /> 
    13.                 <category android:name="android.intent.category.LAUNCHER" /> 
    14.             </intent-filter> 
    15.         </activity> 
    16.      <service android:name="RemoteService"> 
    17.             <intent-filter> 
    18.                 <action android:name="com.android.aidl.action.MY_REMOTE_SERVICE"/> 
    19.             </intent-filter> 
    20.     </service> 
    21.     </application> 
    22. </manifest> 

    效果图:

  • 相关阅读:
    指定时间的月初和月末一天的写法
    EF写distinct
    服务的调试和安装
    EF写INNER JOIN 链接
    BZOJ 1825: [JSOI2010]蔬菜庆典
    P4171 [JSOI2010]满汉全席
    Educational Codeforces Round 71 (Rated for Div. 2) Solution
    P4292 [WC2010]重建计划
    P3724 [AH2017/HNOI2017]大佬
    P5504 [JSOI2011]柠檬
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3571963.html
Copyright © 2020-2023  润新知