深入浅出 Android核心组件Service(4)
2013-09-09 21:04
190 查看
本文51CTO专栏作者傻蛋将向我们介绍深入浅出 Android核心组件Service第四部分的系列文章。
AD: 2013云计算架构师峰会超低价抢票中
在Android平台中,一个进程通常不能访问其他进程中的内存区域的。但是,我们可以使用IDL语言来把对象伪装成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。
如果想在应用程序中调用其他进程中的Service,则需要用到AIDL,AIDL(android接口描述语言)是一种IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
使用AIDL的方法如下:
1.首先要编写一个 IMusicService.aidl的服务接口,ADT会根据这个接口文件帮我们自动生成一个 Stub类,这个类继承了Binder类,同时继承了IMusicService这个接口,还可以看到其中包含了一个Proxy代理类,以实现远程代理,访问不同的进程。(aidl和Stub类如下所示)。
2. 生成的Stub类如下,我们暂不做详细讲解,后面的课程中我们会尝试自己来写一个类似的类,完成不同进程的访问。
3. 在Activity中得到Binder的方式,是通过Stub类的IMusicService.Stub.asInterface(binder)方法(这一点和以前不同)。相应的代码如下:
4. 最后在此Service注册的时候我们需要指定它是在一个不同的进程中运行的,本例子指定的是remote进程。注意 process参数。
本节的源代码可在此下载:http://down.51cto.com/data/326382
AD: 2013云计算架构师峰会超低价抢票中
在Android平台中,一个进程通常不能访问其他进程中的内存区域的。但是,我们可以使用IDL语言来把对象伪装成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。
如果想在应用程序中调用其他进程中的Service,则需要用到AIDL,AIDL(android接口描述语言)是一种IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
使用AIDL的方法如下:
1.首先要编写一个 IMusicService.aidl的服务接口,ADT会根据这个接口文件帮我们自动生成一个 Stub类,这个类继承了Binder类,同时继承了IMusicService这个接口,还可以看到其中包含了一个Proxy代理类,以实现远程代理,访问不同的进程。(aidl和Stub类如下所示)。
/** * IMusicService.aidl * com.androidtest.service.mediaplayer * * Function: TODO * * ver date author * ────────────────────────────────── * 2011-5-19 Leon * * Copyright (c) 2011, TNT All Rights Reserved. */ package com.zuiniuwang.service; /** * ClassName:IMusicService * Function: TODO ADD FUNCTION * Reason: TODO ADD REASON * * @author Leon * @version * @since Ver 1.1 * @Date 2011-5-19 */ interface IMusicService{ void play(); void pause(); void stop(); }
2. 生成的Stub类如下,我们暂不做详细讲解,后面的课程中我们会尝试自己来写一个类似的类,完成不同进程的访问。
/* * This file is auto-generated. DO NOT MODIFY. * Original file: E:\\myworkspace\\musicservice4\\src\\com\\zuiniuwang\\service\\IMusicService.aidl */ package com.zuiniuwang.service; /** * ClassName:IMusicService * Function: TODO ADD FUNCTION * Reason: TODO ADD REASON * * @author Leon * @version * @since Ver 1.1 * @Date 2011-5-19 */ public interface IMusicService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.zuiniuwang.service.IMusicService { private static final java.lang.String DESCRIPTOR = "com.zuiniuwang.service.IMusicService"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.zuiniuwang.service.IMusicService interface, * generating a proxy if needed. */ public static com.zuiniuwang.service.IMusicService asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.zuiniuwang.service.IMusicService))) { return ((com.zuiniuwang.service.IMusicService)iin); } return new com.zuiniuwang.service.IMusicService.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_play: { data.enforceInterface(DESCRIPTOR); this.play(); reply.writeNoException(); return true; } case TRANSACTION_pause: { data.enforceInterface(DESCRIPTOR); this.pause(); reply.writeNoException(); return true; } case TRANSACTION_stop: { data.enforceInterface(DESCRIPTOR); this.stop(); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.zuiniuwang.service.IMusicService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } public void play() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_play, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } public void pause() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_pause, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } public void stop() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_play = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_pause = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); } public void play() throws android.os.RemoteException; public void pause() throws android.os.RemoteException; public void stop() throws android.os.RemoteException; }
3. 在Activity中得到Binder的方式,是通过Stub类的IMusicService.Stub.asInterface(binder)方法(这一点和以前不同)。相应的代码如下:
/** * RemoteMusicPlayerActivity.java * com.androidtest.activity.musicplayer * * Function: TODO * * ver date author * ────────────────────────────────── * 2011-5-20 Leon * * Copyright (c) 2011, TNT All Rights Reserved. */ package com.zuiniuwang.playeractivity; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.zuiniuwang.R; import com.zuiniuwang.service.IMusicService; /** * ClassName:RemoteMusicPlayerActivity Function: TODO ADD FUNCTION Reason: TODO * ADD REASON * * @author Leon * @version * @since Ver 1.1 * @Date 2011-5-20 */ public class RemoteMusicPlayerActivity extends Activity implements OnClickListener { private static final String TAG = RemoteMusicPlayerActivity.class .getSimpleName(); private Button playButton, pauseButton, stopButton, closeActivityButton, exitActivityButton; private IMusicService musicServiceInterface; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); this.setContentView(R.layout.music_player_layout); findViews(); bindViews(); connection(); } private void findViews() { playButton = (Button) this.findViewById(R.id.play); pauseButton = (Button) this.findViewById(R.id.pause); stopButton = (Button) this.findViewById(R.id.stop); closeActivityButton = (Button) this.findViewById(R.id.close); exitActivityButton = (Button) this.findViewById(R.id.exit); } private void bindViews() { playButton.setOnClickListener(this); pauseButton.setOnClickListener(this); stopButton.setOnClickListener(this); closeActivityButton.setOnClickListener(this); exitActivityButton.setOnClickListener(this); } private void connection() { Intent intent = new Intent( "com.androidtest.service.mediaplayer.RemoteMusicService"); this.startService(intent); this.bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection myServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { musicServiceInterface = IMusicService.Stub.asInterface(binder); Log.d(TAG, " onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { musicServiceInterface = null; Log.d(TAG, " onServiceDisconnected"); } }; @Override public void onClick(View view) { // TODO Auto-generated method stub try { switch (view.getId()) { case R.id.play: Log.d(TAG, "play......."); musicServiceInterface.play(); break; case R.id.pause: Log.d(TAG, "pause......."); musicServiceInterface.pause(); break; case R.id.stop: Log.d(TAG, "stop......."); musicServiceInterface.stop(); break; case R.id.close: //Activity退出之前要解除绑定,不然会报错 this.unbindService(myServiceConnection); Log.d(TAG, "close......."); this.finish(); break; case R.id.exit: Log.d(TAG, "exit......."); this.unbindService(myServiceConnection); this.stopService(new Intent("com.androidtest.service.mediaplayer.RemoteMusicService")); this.finish(); } } catch (Exception e) { e.printStackTrace(); } } }
4. 最后在此Service注册的时候我们需要指定它是在一个不同的进程中运行的,本例子指定的是remote进程。注意 process参数。
<!-- 注册Service --> <service android:enabled="true" android:name=".service.RemoteMusicService" android:process=":remote"> <intent-filter> <action android:name="com.androidtest.service.mediaplayer.RemoteMusicService" /> </intent-filter> </service>
本节的源代码可在此下载:http://down.51cto.com/data/326382
相关文章推荐
- 深入浅出 Android核心组件Service(3)
- 深入浅出 Android核心组件Service(2)
- 深入浅出 Android核心组件Service(5)
- 深入浅出 Android核心组件Service(4)
- 深入浅出 Android核心组件Service(1)
- 10天学通Android开发(2-3)-核心组件Service绑定
- Android核心组件之Service
- Android四大核心组件之Service
- android 应用五大核心组件之一(service)
- Android四大核心组件之Service
- Android核心组件之Service
- Android核心技术之(7)---四大应用组件之Service
- 【Android基础】(2)四大核心组件之Service
- Android 四大核心组件之Service
- 10天学通Android开发(2-2)-核心组件Service创建
- Android四大核心组件之一-----Service(服务)的基本知识
- Android核心基础-11.Android四大组件之Service
- Android四大核心组件之Service:服务
- 【ALearning】第五章 Android相关组件介绍(二)Service
- Android组件之Service生命周期