博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Service与Activity与交流AIDL
阅读量:7833 次
发布时间:2019-07-04

本文共 4308 字,大约阅读时间需要 14 分钟。

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

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

1、Service与Activity沟通

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

    (1)、声明

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

  

(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文件:
    
        
    

    这东西看上去非常像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、使用类似于广播的机制启动远程的服务,并调用该方法。

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

你可能感兴趣的文章
【新手向】TensorFlow 安装教程:RK3399上运行谷歌人工智能
查看>>
Oracle Net Configuration(监听程序和网络服务配置)
查看>>
c语言_判断例子
查看>>
ubuntu重启不清除 /tmp 设置
查看>>
面向对象
查看>>
JSON
查看>>
SAP发布wbservice,如果有权限管控的话,需要给这个webservice加权限
查看>>
16.Python网络爬虫之Scrapy框架(CrawlSpider)
查看>>
stm 常用头文件
查看>>
mac 删除文件夹里所有的.svn文件
查看>>
程序制作 代写程序 软件定制 代写Assignment 网络IT支持服务
查看>>
mysql 案例~select引起的性能问题
查看>>
直接读取图层
查看>>
springsecurity 源码解读 之 RememberMeAuthenticationFilter
查看>>
HTML5标准学习 - 编码
查看>>
JS 时间戳转星期几 AND js时间戳判断时间几天前
查看>>
UVa11426 最大公约数之和(正版)
查看>>
mime
查看>>
SQL练习之求解填字游戏
查看>>
DOM
查看>>