深圳旅游月。终于回来了,做了很多个月,这些天来的东西会慢慢总结出来的。今天,我们正在谈论的Service小东西:沟通。

固定通信的做法比较,基本上按照写模板可以实现。

1、Service与Activity沟通

Activity通过startService()方法启动Service之后,Service将独立于Activity执行(尽管仍然是同一个进程),Activity无法指导Service怎样执行。当Activity须要依据一些条件决定Service怎样执行的时候。就须要有另外的方法了:将Service申明为远程Service。

(1)、声明

将一个服务声明为远程服务仅仅需在manifest文件的声明中加一句process=":remote"。例如以下所看到的:

<service
android:name="com.iflytek.service.PowerService"
android:process=":remote" >
</service>  

(2)Service端

private MyBinder mBinder= new MyBinder();

public IBinder onBind(Intent intent){
return mBinder;
} public MyBinder extends Binder{
public void doSomething(){
Log.d("Timothy", "I am doing something!")
}
}

onBind()方法在创建Service的时候就已经默认创建了,这里仅仅是实现了这种方法。mBinder就像是一座桥梁,连接了Service与Activity。将Service中的接口方法暴露给Activity,让Activity能够通过mBinder去调用这些接口。

(3)Activity端

private MyService.MyBinder myBinder;

private ServiceConnection connection = new ServiceConnection(){
@Override
public void onServiceDisconnected(ComponentName name){ } @Override
public void onServiceConnected(ComponentName name, IBinder service){
myBinder = (MyService.MyBinder)service;
myBinder.doSomething();
}
} Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE);

首先是声明一个MyBInder类。让Activity能够使用这座桥梁。然后就是声明一个ServiceConnection对象。绑定的时候怎样调用Service的方法。最后就是绑定了。

须要说明一点:bindService()函数的第三个參数说明。当绑定服务的时候,将自己主动调用Service的onCreate()方法。

当须要多次调用doSomething()方法的时候,假设直接bindService是会报错的。这时候能够在bind之前加上以下这种一段:

try{
    unbindService(connection);
}catch(Exception e){
    e.printTrace();
}

这样就不会报错了。

2、AIDL

我在开发中遇到的问题是:应用层app须要在一定的条件下调用系统的休眠和关机。而休眠和关机的接口仅仅有系统级应用才干调用,这样就必须在系统层为应用提供可以远程调用的服务了。

上面说的远程服务,实际上依旧是在同一个project中,可是我面对的问题非常明显,是全然独立的两个应用,怎么样才干在project1的类中引用到project2中的类呢?

Google为此提供了一个叫做AIDL的东西。也就是Android Interface Describe Language。用这个东东作为调用的桥梁。

关于AIDL的理论这里不多说。在此仅仅介绍其使用方法。

(1)Service端

a、首先是改动manifest文件:

<service
    android:name="com.iflytek.service.PowerService"
    android:process=":remote" >
    <intent-filter>
        <action android:name="com.iflytek.vbox.power" />
    </intent-filter>
</service>

这东西看上去非常像Broadcast Receiver的声明,推測其内部实现也应该和广播差点儿相同。

b、新建一个package,在package中新建AIDL文件。声明好Activity与Service通信的方法:

package com.***.aidl;

interface MyService{
void goToSleep();
void shutDown();
}

注意这里不能用public、private修饰。编写好保存之后,将在gen文件夹下自己主动生成一个Java文件,这个文件不须要维护。

c、改动PowerService文件,实现上面声明的接口。

public class PowerService extends Service {
MyService.Stub mBinder;
PowerManager pm;
String filePath;
Handler handler; @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
} @Override
public void onCreate() {
super.onCreate(); mBinder = new Stub() {
@Override
public void goToSleep() throws RemoteException {
Tools.writeLog("PowerService.goToSleep() is called");
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
SleepThread sleepThread = new SleepThread(pm);
sleepThread.start();
} @Override
public void shutDown() throws RemoteException {
ShutDownThread shutDownThread = new ShutDownThread();
shutDownThread.start();
}
};
}
}

这里就是用mBinder实现了接口。

接口中我启动了子线程去做真正的运行工作。这也是比較常见的使用方法。这里写法比較固定。照抄就好。

(2)Activity端

a、将Service中的AIDL连package一起复制过来,记得,是要连package一起。

b、開始抄吧

private MyService myService;
private static ServiceConnection sleepConnection;
private static ServiceConnection shutdownConnection; sleepConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
Log.d("Timothy", "sleepConnection connected");
myService = MyService.Stub.asInterface(arg1);
try {
myService.goToSleep();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @Override
public void onServiceDisconnected(ComponentName arg0) { }
}; shutdownConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
Log.d("Timothy", "shutdownConnection");
myService = MyService.Stub.asInterface(arg1);
try {
myService.shutDown();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @Override
public void onServiceDisconnected(ComponentName arg0) { }
}; Intent sleepIntent = new Intent("com.***.***.power");
bindService(sleepIntent, sleepConnection, BIND_AUTO_CREATE); Intent updateIntent = new Intent("com.***.***.power");
bindService(updateIntent, updateConnection, BIND_AUTO_CREATE);

能够看到,这里和上面的远程服务差的不多,也是在bind的时候调用Service的方法。

细致看看上面的写法,你就会发现AIDL的精妙之处就在于:1、将远程接口声明在本地,这样就能像本地类一样调用远程方法。符合Java的语法规则。2、使用类似于广播的机制启动远程的服务,并调用该方法。

版权声明:本文博主原创文章,博客,未经同意不得转载。

Service与Activity与交流AIDL的更多相关文章

  1. aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法

    说明:我没有写实例代码,直接拿项目中的代码,有点懒了,这里我省略贴出两个aidl文件. TtsService extends Service private final RemoteCallbackL ...

  2. 本地/远程Service 和Activity 的交方式(转)

    android SDK提供了Service,用于类似*nix守护进程或者windows的服务. Service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remo ...

  3. 关于android编程中service和activity的区别

    一. 绝大部分情况下,Service的作用是用来“执行”后台的.耗时的.重要的任务,三者缺一不可,而最重要的原因是第三点:要执行重要的任务. 因为当一个进程启动了Service后,进程的优先级变高了, ...

  4. Service官方教程(11)Bound Service示例之2-AIDL 定义跨进程接口并通信

    Android Interface Definition Language (AIDL) 1.In this document Defining an AIDL Interface Create th ...

  5. Android—Service与Activity的交互

    service-Android的四大组件之一.人称"后台服务"指其本身的运行并不依赖于用户可视的UI界面 实际开发中我们经常需要service和activity之间可以相互传递数据 ...

  6. Android Service与Activity之间通信

    主要分为: 通过Binder对象 通过broadcast(广播)的形式 Activity调用bindService (Intent service, ServiceConnection conn, i ...

  7. Android Service与Activity之间通信的几种方式

    在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,我们一般在Activ ...

  8. Android学习笔记(九)一个例子弄清Service与Activity通信

    上一篇博文主要整理了Service的创建.绑定过程,本篇主要整理一下Service与Activity的通信方式.包括在启动一个Service时向它传递数据.怎样改变运行中的Service中得数据和侦听 ...

  9. android开发之使用Messenger实现service与activity交互

    service与activity交互的方式有多种,这里说说使用Messenger来实现两者之间的交互. Service程序 public class MessengerService extends ...

随机推荐

  1. POJ 3450 Corporate Identity KMP解决问题的方法

    这个问题,需要一组字符串求最长公共子,其实灵活运用KMP高速寻求最长前缀. 请注意,意大利愿父亲:按照输出词典的顺序的规定. 另外要提醒的是:它也被用来KMP为了解决这个问题,但是很多人认为KMP使用 ...

  2. (摘录)SQL Server 存储过程

    文章摘录:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110862.html SQL Server 存储过程 Transact-SQL中的存储过程 ...

  3. 程序员之---C语言细节22(函数返回指针注意事项&lt;悬空指针&gt;、查看进程能够分配的内存大小)

    主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static ...

  4. python中使用traceback来追踪异常

    test1.py中,当分母为0的时候,调用系统退出 #!/usr/bin/python import sys def division(a=1, b=1): if b==0: print 'b eq ...

  5. OTG驱动分析(二)

    上回介绍了OTG功能的 OTG部分驱动,本片分析OTG功能的从设备部分驱动.从设备的注冊过程和OTG的一样,首先注冊设备. 流程是: 1.定义platform_device结构. 2.定义platfo ...

  6. 设计模式——工厂模式(Factory)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 工厂模式定 ...

  7. vc++笔记十一

    一.LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 连接器LNK是通过调用cvtres.exe完毕文件向coff格式的转换的,所以出现这样的错误的原因就是cvtres.exe出现了问题 ...

  8. c++ primer 函数传值1

    不看c++ primer  永远不知道自己基础有多差 函数的參数传值一般有两种方式:值传递,引用传递. 值传递有以下两种形式: void func( int a ) { // } void func1 ...

  9. 实现能够直接粘QQ贴截图的bug管理功能

    对于一个功能强大的协作平台来说,todo管理和bug管理是不可缺少的功能.Todo和bug往往不是通过一些简单的文字就能实现的,有时候须要配以图片的说名,之前用过的项目管理平台都是以附件的形式上传图片 ...

  10. CSS设计指南之理解盒子模型

    原文:CSS设计指南之理解盒子模型 一.理解盒模型 每一个元素都会在页面上生成一个盒子.因此,HTML页面实际上是由一堆盒子组成的.默认情况下,每个盒子的边框不可见,背景也是透明的,所以我们不能直接看 ...