综合实例2:client訪问远程Service服务
实现:通过一个button来获取远程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. }
位置例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

    编写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综合实例二的更多相关文章

  1. Android笔记(七十四) 详解Intent

    我们最常使用Intent来实现Activity之间的转跳,最近做一个app用到从系统搜索图片的功能,使用到了intent的 setType 方法和 setAction 方法,网上搜索一番,发现实现转跳 ...

  2. Android笔记(六十四) android中的动画——补间动画(tweened animation)

    补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...

  3. 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头

    摄像机切换镜头 在游戏中常常会切换摄像机来观察某一个游戏对象,能够说.在3D游戏开发中,摄像头的切换是不可或缺的. 这次我们学习总结下摄像机怎么切换镜头. 代码: private var Camera ...

  4. Android笔记(十四) Android中的基本组件——按钮

    Android中的按钮主要包括Button和ImageButton两种,Button继承自TextView,而ImageButton继承自ImageView.Button生成的按钮上显示文字,而Ima ...

  5. tensorflow学习笔记(三十四):Saver(保存与加载模型)

    Savertensorflow 中的 Saver 对象是用于 参数保存和恢复的.如何使用呢? 这里介绍了一些基本的用法. 官网中给出了这么一个例子: v1 = tf.Variable(..., nam ...

  6. PHP学习笔记三十四【记录日志】

    <?php function my_error2($errno,$errmes) { echo "错误号:".$errno; //默认时区是格林威治相差八个时区 //设置 1 ...

  7. 论文阅读笔记三十四:DSSD: Deconvolutiona lSingle Shot Detector(CVPR2017)

    论文源址:https://arxiv.org/abs/1701.06659 开源代码:https://github.com/MTCloudVision/mxnet-dssd 摘要 DSSD主要是向目标 ...

  8. Python学习日记(三十四) Mysql数据库篇 二

    外键(Foreign Key) 如果今天有一张表上面有很多职务的信息 我们可以通过使用外键的方式去将两张表产生关联 这样的好处能够节省空间,比方说你今天的职务名称很长,在一张表中就要重复的去写这个职务 ...

  9. Java开发学习(三十四)----Maven私服(二)本地仓库访问私服配置与私服资源上传下载

    一.本地仓库访问私服配置 我们通过IDEA将开发的模块上传到私服,中间是要经过本地Maven的 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码 私服中的仓库很多,Maven最终要把资源 ...

随机推荐

  1. mysql 查询格式化时间

    select DATE_FORMAT(addtime,'$m %d %Y') from tablename 输出:01 28 2019 数据库时间格式:2019-01-28 15:01:20

  2. C语言编译和链接

    编译链接是使用高级语言编程所必须的操作,一个源程序只有经过编译.链接操作以后才可以变成计算机可以理解并执行的二进制可执行文件. 编译是指根据用户写的源程序代码,经过词法和语法分析,将高级语言编写的代码 ...

  3. mysql给某字段随机赋特定范围的整数值

    [引] mysql中随机生成一些范围内的整数有时候是很有用的,用到了2个函数 1.floor(f) 返回一个不大于f的最大整数 2.rand(),rand(n) 返回一个随机浮点值 v ,范围在 0  ...

  4. 实验了一下对于struct引用的成员的改动

    今天写代码的时候,不确定struct用引用传递给函数的时候,他的成员在函数里面改变的时候,是否能影响到外面. 实验了一下 #include <stdio.h> #include <s ...

  5. HDU--4891--The Great Pan--暴力搜索

    The Great Pan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  6. [MST] Store Store in Local Storage

    For an optimal user and developer experience, storing state in local storage is often a must. In thi ...

  7. Data Member Order

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-member-order In some appl ...

  8. iOS自动布局高级用法 && 纯代码约束写法

    本文主要介绍几个我遇到的总结的高级用法(当然我相信肯定有不少比这还高级的). 简单的storyboard中上下左右约束,固定宽高啥的用法在这里就不做赘述了. autolayout自动布局是iOS6以后 ...

  9. 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否

    基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...

  10. PostgreSQL Replication之第一章 理解复制概念(3)

    1.3 使用分片和数据分配 本节您将了解基本可扩展性技术,例如数据库分片.分片被广泛应用于高端系统并提供一个简单而且可靠的扩展设置方式来向外扩展.近年来,分片已经成为一种扩大专业系统规模的标准方式. ...