android service 学习(下)

android service 学习(下)  

通常每个应用程序都在它自己的进程内运行,但有时需要在进程间传递对象,你可以通过应用程序UI的方式写个运行在一个不同的进程中的service。在android平台中,一个进程通常不能访问其他进程中的内存区域。所以,他们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。编写这种伪装代码相当的枯燥乏味,好在android为我们提供了AIDL工具可以来做这件事。

AIDL(android接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Service的实现类需要去继承这个stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:

先创建一个IMyRemoteService.aidl文件

package org.allin.android.remote;
interface IMusicControlService{
        void play(); 
        void stop(); 
        void pause();
}

如果你正在使用eclipse的Android插件,则它会根据这个aidl文件生成一个Java接口类。生成的接口类中会有一个内部类Stub类,你要做的事就是去继承该Stub类:

/**
 * @author allin.dev
 * http://allin.cnblogs.com/
 *
 */
public class RemoteMusicService extends Service {

	private static final String TAG = "RemoteMusicService";
	private MediaPlayer mediaPlayer;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return binder;
	}

	private final IMusicControlService.Stub binder = new IMusicControlService.Stub() {

		@Override
		public void stop() throws RemoteException {
			Log.d(TAG,"stop....");
			if (mediaPlayer != null) {
				mediaPlayer.stop();
				try {
					// 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
					mediaPlayer.prepare();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}

		}

		@Override
		public void play() throws RemoteException {
			Log.d(TAG,"play....");
			if (mediaPlayer == null) {
				mediaPlayer = MediaPlayer.create(RemoteMusicService.this,
						R.raw.tmp);
				mediaPlayer.setLooping(false);
			}
			if (!mediaPlayer.isPlaying()) {
				mediaPlayer.start();
			}
		}

		@Override
		public void pause() throws RemoteException {
			Log.d(TAG,"pause....");
			
			if (mediaPlayer != null && mediaPlayer.isPlaying()) {
				mediaPlayer.pause();
			}			
		}

	};
	
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		
		Log.d(TAG, "onDestroy");
		if(mediaPlayer != null){
			mediaPlayer.stop();
			mediaPlayer.release();
		}
	}
}

当客户端应用连接到这个Service时,onServiceConnected方法将被调用,客户端就可以获得IBinder对象。参看下面的客户端onServiceConnected方法:

private ServiceConnection sc = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			musicService = null;
			Log.d(TAG, "in onServiceDisconnected");
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			musicService = IMusicControlService.Stub.asInterface(service);
			Log.d(TAG, "in onServiceConnected");
		}
	};

启动后的界面如下

[源码下载]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏非著名程序员

Android 图片选择到裁剪之步步深坑

前言 最近在自己的项目里实现了一个头像选择的功能,就是先从相册里选取一张图片再调用系统的裁剪功能来制作头像,效果就像下面这样: ? 本以为很小的一个功能,却远远...

49680
来自专栏非著名程序员

如何解决 Android Studio 上远程依赖包重复的问题

你们是不是会经常遇到这样的一个错误:com.android.dex.DexException: Multiple dex files define XXXX,一...

392100
来自专栏非著名程序员

强烈推荐:基于Java反射实现一个 Android ORM 框架

今天给大家推荐一个不错的开源项目代码,作者利用反射机制实现了数据库的 ORM 框架。希望大家读了之后能够从中学习作者的思路和思想。再重复一遍,学习一下作者的思路...

55880
来自专栏非著名程序员

一睹妆容,Android 8.0 开发者预览版来了

一年一年的更新,一年比一年好,一年又一年的期待,可是国内手机用户,现在大多数还停留在 5.0 ,6.0 的 Android 系统年代,7.0 牛轧糖什么味还有很...

213100
来自专栏非著名程序员

Android的编译打包流程详解

阅读本文可以让获得如下知识:(1)Android编译打包流程。(2) Android是如何通过R文件引用到真正的资源文件?(3)打包流程中的的对齐是什么,为什么...

249100
来自专栏非著名程序员

Android 高效安全的本地广播 LocalBroadcast 完全解析

背景 广播作为Android 四大组件有非常广泛的用途。广播可以用作进程间通信,也会用作进程内部某些组件内消息的传递。 这就会有个问题,如果想让发送的广播只有我...

32570
来自专栏非著名程序员

Android 仿京东、拼多多商品分类页

最近接了一个项目,要仿照京东写一个商品分类页,但需要滑动右边子分类,左边的主分类也跟着变换,写了个demo,需要的同学可以自取。 先放一个写完之后的样子: ?...

58590
来自专栏非著名程序员

简单高效的实现 Android App 全局字体替换

Android O推出了一项新的功能「Fonts in XML」,借助这项功能,我们能够像使用其他资源文件一样使用字体,比较方便地实现App全局字体的替换。 为...

40590
来自专栏非著名程序员

基于 RxJava2+Retrofit2 精心打造的 Android 基础框架 XSnow

XSnow ? 基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络、上传、下载、缓存、事件总线、权限管理、数据库、图片加载、UI模...

34670
来自专栏非著名程序员

良心推荐:总结 Android 开发中必备的代码 Review 清单

本文收集了我自己工作以来提交代码前的所有检查点。事实证明,这样能有效提高自己的代码质量和功能的稳定性。所以推荐大家以后每次提交代码前,都可以看下这份 Revie...

25550

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励