Android远程服务编写和调用教程

网上汗牛充栋的文章都是介绍Android远程服务的,一个个将Binder机制、AIDL讲得头头是道,然而没有几个人能够给出清晰的范例说明如何用最快的方法学会编写和调用一个Android远程服务。若你仅仅是想如何编写或者调用Android的远程服务,而懒得去理解Binder机制是如何运行的,那么本篇文章正好适合你。毕竟现在人人都会开车,但没有几个人明白发动机到底是如何运作的。

预备知识

读者应该有基本的java知识,和Android简单app的开发经验。

环境

代码运行环境:
1.ADT2014版本;
2.android:minSdkVersion=”8”;android:targetSdkVersion=”20”
3.workspace中已经生成了appcompatv7,它的版本是android-22;

远程服务开发教程

在开始开发之前,先弄清楚几个概念:
1. IPC:进程间通信,你只需要知道Android是依赖这个东西来进行远程服务调用的就可以了。
2. Binder机制:Android发明的一种IPC机制,据说非常非常的好,你就当它是个黑盒子,通过这个黑盒子就可以进行远程服务调用了,而且Android中的很多机制都是通过它实现的。
3. AIDL语言:一种专门用来写远程接口的语言,看它的名字就知道了,Android Interface Definition
Language。AIDL语言可以被android提供的编译器编译为Java源代码,这个Java源代码将会被服务的和客户端使用,用来简化远程服务开发流程。如果你当初玩过CORBA,那就更能明白什么是IDL语言了
4. IInterface接口、IBinder接口、IBinder类等等:都是用来实现Binder机制的接口和类,在本教程中,你就当它们是Binder黑盒子的一部分,不需要了解。
再说一点,其实Android提供的ApiDemos中就有一个远程服务的标准范例,但是其一是它没有将服务端和客户端分开写,其二是例子中掺杂了太多其他的功能,因此理解起来较为困难。这个例子是com.example.android.apis.app.RemoteService,有兴趣的可以在看完本文后再去详细研究。

第一步,创建一个普通Android应用

应用名为WxbRemoteService,这个应用可以删掉其Activity类,但是为了简单,我们就保留所有自动创建的代码。

第二步,编写AIDL

AIDL语言的语法和Java其实很像,你甚至可以先编写一个Java接口,然后删掉public、protected、private这些权限限定词即可。例子如下IWxbService.aidl:

package com.dumaisoft.wxbremoteservice;

interface IWxbService {
 void setName(String name);
 String getName();
}

注意几点:
1.接口名和aidl文件名相同。
2.接口和方法前不用加访问权限修饰符public,private,protected等,也不能用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,不能为其它标记
IWxbService.aidl文件的位置是在com.dumaisoft.wxbremoteservice包中,只要语法正确,则会在ADT的gen目录下的com.dumaisoft.wxbremoteservice包中生成java文件IWxbService.java。
IWxbService.aidl定义了一个远程接口,它包含两个方法getName和setName。

第三步,编写服务类

添加一个WxbService类,它继承了Service类,源代码如下:

package com.dumaisoft.wxbremoteservice;

import com.dumaisoft.wxbremoteservice.IWxbService.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class WxbService extends Service {

 private ServiceImpl serviceImpl;

 //继承由IWxbService.aidl生成的com.dumaisoft.wxbremoteservice.IWxbService.Stub类
 class ServiceImpl extends Stub{
  private String _name;
  @Override
  public void setName(String name) throws RemoteException {
   _name = name;
  }

  @Override
  public String getName() throws RemoteException {
   return _name;
  }
 }

 //将ServiceImpl做一个简单的单例模式
 private ServiceImpl getInstance(){
  if(serviceImpl == null){
   serviceImpl = new ServiceImpl();
  }
  return serviceImpl;
 }

 @Override
 public IBinder onBind(Intent intent) {
  return getInstance();
 }
}

通过研究代码可知,和普通的服务类相比,远程服务类最大的区别就是它拥有一个名为ServiceImpl的成员变量,这个成员变量继承了Stub类,并实现了Stub类的getName和setName方法。这个Stub类就是由 IWxbService.aidl生成的IWxbService.java提供的。我们不用研究其源代码,只用知道它的用法:
第一:让Service的一个成员变量继承Stub,并实现远程接口的方法;
第二:在Service的onBind方法中返回一个Stub子类的实例。

第四步,配置AndroidManifest.xml

加上如下代码:

  <service android:name="WxbService">
   <intent-filter>
    <action android:name="com.dumaisoft.wxbremoteservice.REMOTE_SREVICE"/>
   </intent-filter>
  </service>

注意action的name为”com.dumaisoft.wxbremoteservice.REMOTE_SREVICE”,这个由开发者保证不重名即可。

第五步,安装app到手机上

安装完成后,你的远程服务就被注册到Binder黑盒子中了,任何客户端只要知道你的远程服务action名称和接口,就可以bind服务,并调用接口。

远程服务调用教程

第一步,创建一个android应用

应用名为WxbRemoteServiceClient,src包中自动生成了com.dumaisoft.wxbremoteserviceclient包。

第二步,引入远程服务的AIDL文件

在src包中创建com.dumaisoft.wxbremoteservice包(为了与服务端的包名相同),然后将上面编写的IWxbService.aidl文件拷贝入此目录。显然,在本工程的gen目录中也生成了IWxbService.java文件。

第三步,编写调用远程服务的代码

代码如下:

package com.dumaisoft.wxbremoteserviceclient;

import com.dumaisoft.wxbremoteservice.IWxbService;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
 private Button btnBind;
 private Button btnSetName;
 private Button btnGetName;
 private IWxbService serviceProxy; //远程服务的代理
 private ServiceConnection conn = new ServiceConnection() {

  @Override
  public void onServiceDisconnected(ComponentName name) {
  }

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   //获取远程服务代理
   serviceProxy = IWxbService.Stub.asInterface(service);
  }
 };

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  btnBind = (Button) this.findViewById(R.id.btnBind);
  btnSetName = (Button) this.findViewById(R.id.btnSetName);
  btnGetName = (Button) this.findViewById(R.id.btnGetName);
  btnBind.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    Intent service = new Intent();
    //Remote Service Action name
    service.setAction("com.dumaisoft.wxbremoteservice.REMOTE_SREVICE");
    bindService(service, conn, Service.BIND_AUTO_CREATE);
   }
  });
  btnSetName.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    try {
     serviceProxy.setName("MyName");
    } catch (RemoteException e) {
     e.printStackTrace();
    }
   }
  });
  btnGetName.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    try {
     String name = serviceProxy.getName();
     Toast.makeText(getApplicationContext(), name, Toast.LENGTH_LONG).show();
    } catch (RemoteException e) {
     e.printStackTrace();
    }
   }
  });
 }
}

注意几点:
一、创建一个ServiceConnection的匿名子类,在其onServiceConnected方法中获取远程服务代理对象serviceProxy。事实上,onServiceConnected方法会在bindService方法调用时被调用,因此能确保一定可以获得远程服务的代理对象;
二、IWxbService.Stub.asInterface(service)方法也是由IWxbService.java文件提供的,其内部机制不用研究,只需要知道它会返回一个IWxbService接口的对象,该对象可以通过Binder黑盒子调用远程服务的setName和getName方法;
三、使用Intent指定action为”com.dumaisoft.wxbremoteservice.REMOTE_SREVICE”,即可正确的bind到远程服务。
四、bind成功后,就可以通过远程服务的代理对象,使用远程服务的功能了。

小结

至此,读者应该能比较快速的开发出一个远程服务,并能编写客户端轻松的调用它了。还有一点需要说明的是,除了使用AIDL来进行远程服务的编写和调用外,还可以直接使用IBinder、Binder等接口和类来进行远程服务编写调用。

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • 将MSSQL Server 导入/导出到远程服务器教程的图文方法分享

    1.打开本地企业管理器,先创建一个SQL Server注册来远程连接服务器端口SQL Server.步骤如下图: 图1: 2.弹出窗口后输入内容."总是提示输入登陆名和密码"可选可不选,如图2. 图2: 3.注册好服务器后,点击打开.如果是选择了"总是提示输入登陆名和密码"的话再点了确定后会提示输入用户密码,如图3. 图3: 4.进入后,选择到您的数据库,如testdb.在上面点右键,"所有任务">>"导入数据",

  • python 从远程服务器下载东西的代码

    复制代码 代码如下: # _*_ coding:utf-8 _*_# name gefile.pyimport osimport statimport socketimport paramikoFILES=["filenameA","filenameB","filenameC","filenameD","filenameE"]USERNAME="root"PASSWORD="1

  • 可以从一台远程服务器运行 SP2 安装程序Install.vbs

    Install.vbs 发布者 Microsoft Corporation 脚本专家 此脚本由 scenario1.vbs 在一台网络主机上启动.Install.vbs 可以在安装了 SP2 的主机上以本地方式运行,它执行以下任务: ? 从一台远程服务器运行 SP2 安装程序. ? 在主机上设置 AutoAdmin 和 RunOnce 两个注册表项. ? 将结果记录到文本文件 computername-sp2-instlog.txt 并将该文件复制回管理工作站. ? 强制重新启动,随后 runo

  • 利用ASP从远程服务器上接收XML数据的方法

    复制代码 代码如下: <%  dim objXML  dim objRootElement  dim strValue  dim strInetURL  dim strXML  dim item              strInetURL ="http://pf.inetsolution.com/inetactive2001/inetactive2001news.xml"  Dim HttpReq   set HttpReq = server.CreateObject(&qu

  • ColdFusion MX 远程服务实例入门教程

    这个教程分二个部分:1 创建CF组件2创建flash应用.在开始之前请新建一个站点.一 创建CF组件:这里我们创建一个组件 定义二个函数[chaxun1,chaxun2],函数使用exampleapps 数据库源,返回一个查询结果对象, flash电影文件调用组件方法和接收返回的查询结果.chaxun1函数需要三个参数,这些参数从flash电影中传递过来.(参数为xing ming cheng)    创建的步奏如下所示: 使用dwmx(Dreamweaver MX的简称,下同), 文件→新建:

  • C# FTP,GetResponse(),远程服务器返回错误

    FtpWebRequest类实现ftp功能的一般过程 1.创建一个FtpWebRequest对象,指向ftp服务器的uri 2.设置ftp的执行方法(上传,下载等) 3.给FtpWebRequest对象设置属性(是否支持ssl,是否使用二进制传输等) 4.设置登录验证(用户名,密码) 5.执行请求 6.接收相应流(如果需要的话) 7.如果没有打开的流,则关闭ftp请求 其中一些重要的属性如下: ·Credentials - 指定登录ftp服务器的用户名和密码. ·KeepAlive - 指定连接

  • 利用xcopy命令实现本地文件复制到远程服务器的方法

    A.net use \\IP地址 密码/user:****** B.xcopy 文件 \\IP地址\ 批处理文件为backup.bat,其代码如下: ========================================================================================= net use \\192.168.1.198\ipc$ Zqf198703 /user:royalpeak xcopy g:\backup\*.* \\192.168.

  • java判断远程服务器上的文件是否存在的方法

    在做数据文件导入到   LEFTII   中是遇到一个文件,在做导入的时候有时候生成的原始文件可能不存在,现在通过加一个判断,判断文件是否存在,起初以为简单的判断文件   file.exists()   存不存在就行了,但是后来事实证明这个只能判断本地的文件是否存在. 这里我们通过一个巧妙的方法告诉大家,就是把远程的文件共享到本地来,通过电脑的衍射可以轻而易举的解决这个问题 过程如下 然后在下面的步骤输入用户名,密码,这样就可以通过判断本地是否存在这个文件就搞定了.

  • python 从远程服务器下载日志文件的程序

    复制代码 代码如下: import osimport sysimport ftplibimport socket ################################################################### sign in the ftp server and download the log file. # 登陆生产服务器下载日志##############################################################

  • Android远程服务编写和调用教程

    网上汗牛充栋的文章都是介绍Android远程服务的,一个个将Binder机制.AIDL讲得头头是道,然而没有几个人能够给出清晰的范例说明如何用最快的方法学会编写和调用一个Android远程服务.若你仅仅是想如何编写或者调用Android的远程服务,而懒得去理解Binder机制是如何运行的,那么本篇文章正好适合你.毕竟现在人人都会开车,但没有几个人明白发动机到底是如何运作的. 预备知识 读者应该有基本的java知识,和Android简单app的开发经验. 环境 代码运行环境: 1.ADT2014版

  • Android开发中用Kotlin编写LiveData组件教程

    目录 1.简单使用 2.map和switchMap LiveData是Jetpack提供的一种响应式编程组件,它可以包含任何类型的数据,并在数据发生变化的时候通知给观察者.也就是说,我们可以将数据使用LiveData来包装,然后在Activity中去观察它,就可以主动将数据变化通知给Activity了. 1.简单使用 class MainViewModel(countReserved:Int) : ViewModel() { /*当外部调用counter变量时,实际上获得的就是_counter的

  • Android Activity之间相互调用与传递参数的原理与用法分析

    本文实例讲述了Android Activity之间的相互调用与传递参数.分享给大家供大家参考,具体如下: Activity之间是如何调用的 在javaWeb程序中,jsp与jsp之间的调用是通过重定向完成的,而在Android中,Activity与Activity之间的切换是通过Intent来完成的. 所谓Intent,它是Android中非常重要的内置组件,他可以理解为"我要干一件什么事情".在Android中有3大组件:Activity,Service.Broadcast,他们之间

  • android蓝牙简单开发示例教程

    目录 概述 1.权限申请 2.打开蓝牙 3.接收蓝牙状态的改变 4.扫描其他的设备 5.蓝牙配对 6.获取已经配对的设备 7.连接设备 概述 前段时间学习了一些蓝牙开发的知识,记录一下Android中蓝牙的简单开发.下面是最重要的两个类. BluetoothAdapter : 蓝牙适配器,通过getDefaultAdapter ()去获取一个实例,如果设备不支持蓝牙的话,返回的是一个null对象,通过它,可以打开.关闭蓝牙,扫描设备.向指定设备创建socket通道- BluetoothDevic

  • Android 超详细SplashScreen入门教程

    这次的Android系统变化当中,UI的变化无疑是巨大的.Google在Android 12中采取了一种叫作Material You的界面设计,一切以你为中心,以你的喜好为风格.相信大家一旦上手Android 12之后应该能立刻察觉到这些视觉方面的变化. 关于这个SplashScreen,今天就值得好好讲一讲了. 什么是SplashScreen SplashScreen其实通俗点讲就是指的闪屏界面.这个我们国内开发者一定不会陌生,因为绝大多数的国内App都会有闪屏界面这个功能,很多的App还会利

  • 图解Windows环境下Android Studio安装和使用教程

    鉴于谷歌最新推出的Android Studio备受开发者的推崇,所以也跟着体验一下. 一.介绍Android Studio  Android Studio 是一个Android开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试. 最近,Google 已宣布,为了简化 Android 的开发力度,以重点建设 Android Studio 工具,到今年年底将停止支持Eclipse等其他集成开发环

  • Android WebView 应用界面开发教程

    WebView组件本身就是一个浏览器实现,Android5.0增强的WebView基于Chromium M37,直接支持WebRTC.WebAudio.WebGL.开发者可以直接在WebView中使用聚合(Polymer)和Material设计. 一.WebView浏览网页(加载线上URL) WebView提供了很多方法执行浏览器操作,常用方法如下: void goBack():后退 void goForward():前进. void goBackOrForward(int step):step

  • Android studio配置lambda表达式教程

    Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁.当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口. 但是目前的Android Studio还不支持Java8新特性,因此为了使用它只能曲线救国了:借助retrolambda 1.将你的jdk升级成1.8,然后配置好环境 2.将你的sdk更新至24 3.在项目的Project gradle文件配置retrolambda插件的地址: 如下: buildscript { repositories { jce

  • 使用Android studio编写一个小的jni程序

     1.简单介绍一下NDK和JNI NDK:NDK是Native Development Kit的缩写,是Google提供的一套工具集,可以让你其他语言(C.C++或汇编)开发 Android的 JNI.NDK可以编译多平台的so,开发人员只需要简单修改 mk 文件说明需要的平台,不需要改动任何代码,NDK就可以帮你编译出所需的so库. JNI:JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 2.打开Android

  • 详解android studio游戏摇杆开发教程,仿王者荣耀摇杆

    最近在做一个山寨版的王者荣耀,刚开始做的时候毫无头绪 摇杆的多点触控做的特别烂 经过几天的思考已完美解决所有问题,下面就和大家分享下这个摇杆的开发思路 若有不正之处,请多多谅解并欢迎指正. 首先这个摇杆要用到较多的数学知识,小编的数学特别烂也就高中水平吧 我们这个摇杆一共就五个按钮,一个移动摇杆.三个技能摇杆和一个普通攻击按钮 最终效果 好了废话少说让我们开始吧 新建一个项目 建好项目之后,我们先新建一个类叫做"画".也是我们的主View 修改Hua.java的代码 public cl

随机推荐