android service 学习(下)

    技术2022-05-20  48

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

     

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

     

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

     先创建一个IMyRemoteService.aidl文件

     

     

    view source print ? 1package org.allin.android.remote; 2interface IMusicControlService{ 3        void play();  4        void stop();  5        void pause(); 6}

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

    view source print ? 01/** 02 * @author allin.dev 03 * http://allin.cnblogs.com/ 04 * 05 */ 06public class RemoteMusicService extends Service { 07   08    private static final String TAG = "RemoteMusicService"; 09    private MediaPlayer mediaPlayer; 10   11    /* 12     * (non-Javadoc) 13      14     * @see android.app.Service#onBind(android.content.Intent) 15     */ 16    @Override 17    public IBinder onBind(Intent intent) { 18        return binder; 19    } 20   21    private final IMusicControlServic<SCRIPT type=text/javascript><!--mce:1--></SCRIPT>e.Stub binder = new IMusicControlService.Stub() { 22   23        @Override 24        public void stop() throws RemoteException { 25            Log.d(TAG,"stop...."); 26            if (mediaPlayer != null) { 27                mediaPlayer.stop(); 28                try { 29                    // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数 30                    mediaPlayer.prepare(); 31                } catch (IOException ex) { 32                    ex.printStackTrace(); 33                } 34            } 35   36        } 37   38        @Override 39        public void play() throws RemoteException { 40            Log.d(TAG,"play...."); 41            if (mediaPlayer == null) { 42                mediaPlayer = MediaPlayer.create(RemoteMusicService.this, 43                        R.raw.tmp); 44                mediaPlayer.setLooping(false); 45            } 46            if (!mediaPlayer.isPlaying()) { 47                mediaPlayer.start(); 48            } 49        } 50   51        @Override 52        public void pause() throws RemoteException { 53            Log.d(TAG,"pause...."); 54               55            if (mediaPlayer != null && mediaPlayer.isPlaying()) { 56                mediaPlayer.pause(); 57            }            58        } 59   60    }; 61       62       63    @Override 64    public void onDestroy() { 65        super.onDestroy(); 66           67        Log.d(TAG, "onDestroy"); 68        if(mediaPlayer != null){ 69            mediaPlayer.stop(); 70            mediaPlayer.release(); 71        } 72    } 73}

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

    view source print ? 01private ServiceConnection sc = new ServiceConnection() { 02           03        @Override 04        public void onServiceDisconnected(ComponentName name) { 05            musicService = null; 06            Log.d(TAG, "in onServiceDisconnected"); 07        } 08           09        @Override 10        public void onServiceConnected(ComponentName name, IBinder service) { 11            musicService = IMusicControlService.Stub.asInterface(service); 12            Log.d(TAG, "in onServiceConnected"); 13        } 14    };

      启动后的界面如下   [源码下载]


    最新回复(0)