AIDL和远程Service调用(一)

20 阅读9分钟
08            <intent -filter="">
09                <action android:name="android.intent.action.MAIN">
10                <category android:name="android.intent.category.LAUNCHER">
11            </category></action></intent>
12        </activity>
13        <activity android:name=".PlayerActivity">
14        </activity>
15        <service android:name=".MusicService" android:enabled="true">
16        </service>
17    </application>
18 
19</uses></manifest>

我们注意到有2个Activity,1个Service,还有读写外部存储的权限声明

3、CoverActivity.java的代码如下:这是个全屏的启动画面,2秒后会跳转到PlayerActivity

01package app.android.elfplayer;
02 
03import android.app.Activity;
04import android.content.Intent;
05import android.os.Bundle;
06import android.os.Handler;
07import android.view.Window;
08import android.view.WindowManager;
09 
10public class CoverActivity extends Activity {
11    /** Called when the activity is first created. */
12    @Override
13    public void onCreate(Bundle savedInstanceState) {
14        super.onCreate(savedInstanceState);
15        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
16        requestWindowFeature(Window.FEATURE_NO_TITLE);
17        setContentView(R.layout.cover);
18 
19        new Handler().postDelayed(new Runnable(){
20 
21             @Override
22             public void run() {
23                 Intent mainIntent = new Intent(CoverActivity.this,PlayerActivity.class);
24                 CoverActivity.this.startActivity(mainIntent);
25                 CoverActivity.this.finish();
26             }
27 
28            }, 2000);
29 
30    }
31}

4、PlayerActivity.java的代码如下:

001package app.android.elfplayer;
002 
003import android.app.Activity;
004import android.content.ComponentName;
005import android.content.Context;
006import android.content.Intent;
007import android.content.ServiceConnection;
008import android.os.Bundle;
009import android.os.Handler;
010import android.os.IBinder;
011import android.os.Message;
012import android.os.RemoteException;
013import android.util.Log;
014import android.view.View;
015import android.widget.ImageButton;
016import android.widget.SeekBar;
017import android.widget.SeekBar.OnSeekBarChangeListener;
018 
019public class PlayerActivity extends Activity {
020 
021    public static final int PLAY = 1;
022    public static final int PAUSE = 2;
023 
024    ImageButton imageButtonFavorite;
025    ImageButton imageButtonNext;
026    ImageButton imageButtonPlay;
027    ImageButton imageButtonPre;
028    ImageButton imageButtonRepeat;
029    SeekBar musicSeekBar;
030 
031    IServicePlayer iPlayer;
032    boolean isPlaying = false;
033    boolean isLoop = false;
034 
035    @Override
036    public void onCreate(Bundle savedInstanceState) {
037        super.onCreate(savedInstanceState);
038        setContentView(R.layout.player);
039 
040        imageButtonFavorite = (ImageButton) findViewById(R.id.imageButtonFavorite);
041        imageButtonNext = (ImageButton) findViewById(R.id.imageButtonNext);
042        imageButtonPlay = (ImageButton) findViewById(R.id.imageButtonPlay);
043        imageButtonPre = (ImageButton) findViewById(R.id.imageButtonPre);
044        imageButtonRepeat = (ImageButton) findViewById(R.id.imageButtonRepeat);
045        musicSeekBar = (SeekBar) findViewById(R.id.musicSeekBar);
046 
047        bindService(new Intent(PlayerActivity.this, MusicService.class), conn, Context.BIND_AUTO_CREATE);
048        startService(new Intent(PlayerActivity.this, MusicService.class));
049 
050        imageButtonPlay.setOnClickListener(new View.OnClickListener() {
051 
052            @Override
053            public void onClick(View v) {
054                Log.i("yao", "imageButtonPlay -> onClick");
055 
056                if (!isPlaying) {
057                    try {
058                        iPlayer.play();
059                    } catch (RemoteException e) {
060                        e.printStackTrace();
061                    }
062                    imageButtonPlay.setBackgroundResource(R.drawable.pause_button);
063                    isPlaying = true;
064 
065                } else {
066                    try {
067                        iPlayer.pause();
068                    } catch (RemoteException e) {
069                        e.printStackTrace();
070                    }
071                    imageButtonPlay.setBackgroundResource(R.drawable.play_button);
072                    isPlaying = false;
073                }
074            }
075        });
076 
077        musicSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
078 
079            @Override
080            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
081            }
082 
083            @Override
084            public void onStartTrackingTouch(SeekBar seekBar) {
085            }
086 
087            @Override
088            public void onStopTrackingTouch(SeekBar seekBar) {
089                if (iPlayer != null) {
090                    try {
091                        iPlayer.seekTo(seekBar.getProgress());
092                    } catch (RemoteException e) {
093                        e.printStackTrace();
094                    }
095                }
096            }
097        });
098 
099        handler.post(updateThread);
100    }
101 
102    private ServiceConnection conn = new ServiceConnection() {
103        public void onServiceConnected(ComponentName className, IBinder service) {
104            Log.i("yao", "ServiceConnection -> onServiceConnected");
105            iPlayer = IServicePlayer.Stub.asInterface(service);
106        }
107 
108        public void onServiceDisconnected(ComponentName className) {
109        };
110    };
111 
112    Handler handler = new Handler() {
113        @Override
114        public void handleMessage(Message msg) {
115        };
116    };
117 
118    private Runnable updateThread = new Runnable() {
119        @Override
120        public void run() {
121            if (iPlayer != null) {
122                try {
123                    musicSeekBar.setMax(iPlayer.getDuration());
124                    musicSeekBar.setProgress(iPlayer.getCurrentPosition());
125                } catch (RemoteException e) {
126                    e.printStackTrace();
127                }
128            }
129            handler.post(updateThread);
130        }
131    };
132 
133}

5、其中用到的IServicePlayer.aidl,放在和Java文件相同的包中,内容如下:

01package app.android.elfplayer;
02interface IServicePlayer{
03    void play();
04    void pause();
05    void stop();
06    int getDuration();
07    int getCurrentPosition();
08    void seekTo(int current);
09    boolean setLoop(boolean loop);
10}

一旦你写好了这个IServicePlayer.aidl文件,ADT会自动帮你在gen目录下生成IServicePlayer.java文件

6、MusicService.java的内容如下:

01package app.android.elfplayer;
02 
03import android.app.Service;
04import android.content.Intent;
05import android.media.MediaPlayer;
06import android.os.IBinder;
07import android.os.RemoteException;
08import android.util.Log;
09 
10public class MusicService extends Service {
11 
12    String tag = "yao";
13 
14    public static MediaPlayer mPlayer;
15 
16    public boolean isPause = false;
17 
18    IServicePlayer.Stub stub = new IServicePlayer.Stub() {
19 
20        @Override
21        public void play() throws RemoteException {
22            mPlayer.start();
23        }
24 
25        @Override
26        public void pause() throws RemoteException {
27            mPlayer.pause();
28        }
29 
30        @Override
31        public void stop() throws RemoteException {
32            mPlayer.stop();
33        }
34 
35        @Override
36        public int getDuration() throws RemoteException {
37            return mPlayer.getDuration();
38        }