android多线程:自己撰写Proxy/Stub播放MP3音乐

来源:互联网 发布:nba2k17科比捏脸数据 编辑:程序博客网 时间:2024/04/30 04:35

一、架构设计

在这个范例中,定义了一个IPlayer接口,然后规划了PlayerProxy和PlayerStub两个类,如下图:


于是,PlayerProxy与PlayerStub分别位于跨进程IPC的两端。

二、完整的实现程序

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.misoo.pxgx"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.misoo.pxgx.ac01"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>                <service            android:name=".Mp3RemoteService"            android:process=".remote" >            <intent-filter>                <action android:name="com.misoo.pkgx.REMOTE_SERVICE" />            </intent-filter>        </service>    </application></manifest>
IPlayer:

package com.misoo.pxgx;public interface IPlayer {void play();void stop();String getStatus();}
Mp3RemoteService

package com.misoo.pxgx;import android.app.Service;import android.content.Intent;import android.os.IBinder;public class Mp3RemoteService extends Service {private IBinder mBinder = null;public void onCreate() {mBinder = new Mp3Binder(getApplicationContext());}public IBinder onBind(Intent intent) {return mBinder;}}
PlayerStub:

package com.misoo.pxgx;import android.os.Binder;import android.os.Parcel;import android.os.RemoteException;public abstract class PlayerStub extends Binder implements IPlayer {protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {reply.writeString(data.readString() + " mp3");if(code == 1) this.play();else if(code == 2) this.stop();return true;}public abstract void play();public abstract void stop();public abstract String getStatus();}
Mp3Binder:

package com.misoo.pxgx;import android.content.Context;import android.media.MediaPlayer;import android.util.Log;public class Mp3Binder extends PlayerStub {private MediaPlayer mediaPlayer = null;private Context ctx;public Mp3Binder(Context cx) {ctx = cx;}public void play() {if(mediaPlayer  != null) return;mediaPlayer = MediaPlayer.create(ctx, R.raw.san);try {mediaPlayer.start();} catch (IllegalStateException e) {Log.e("StartPlay", "error:" + e.getMessage(), e);}}public void stop() {if(mediaPlayer != null){mediaPlayer.stop();mediaPlayer.release();mediaPlayer = null;}}public String getStatus() {return null;}}
ac01:

package com.misoo.pxgx;import android.os.Bundle;import android.os.IBinder;import android.os.Parcel;import android.os.RemoteException;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;public class ac01 extends Activity implements OnClickListener{private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;private final int MP = LinearLayout.LayoutParams.MATCH_PARENT;private Button btn0, btn1, btn2;public TextView tv;private PlayerProxy playerProxy = null;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);LinearLayout layout = new LinearLayout(this);layout.setOrientation(LinearLayout.VERTICAL);btn0 = new Button(this);btn0.setId(101); btn0.setText("play");btn0.setOnClickListener(this);btn1 = new Button(this);btn1.setId(102); btn1.setText("stop");btn1.setOnClickListener(this);btn2 = new Button(this);btn2.setId(103); btn2.setText("exit");btn2.setOnClickListener(this);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(135, 60);params.topMargin = 10;layout.addView(btn0, params);layout.addView(btn1, params);layout.addView(btn2, params);tv = new TextView(this);tv.setText("Ready");LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(MP,  WC);params2.topMargin = 10;layout.addView(tv, params2);setContentView(layout);startService(new Intent("com.misoo.pkgx.REMOTE_SERVICE"));bindService(new Intent("com.misoo.pkgx.REMOTE_SERVICE"),mConnection, Context.BIND_AUTO_CREATE);}private ServiceConnection mConnection = new ServiceConnection() {public void onServiceDisconnected(ComponentName name) {}public void onServiceConnected(ComponentName name, IBinder service) {playerProxy = new PlayerProxy(service);}};public void onClick(View v) {switch(v.getId()){case 101:playerProxy.play();tv.setText(playerProxy.getStatus());break;case 102:playerProxy.stop();tv.setText(playerProxy.getStatus());break;case 103:unbindService(mConnection);stopService(new Intent("com.misoo.pxgx.REMOTE_SERVICE"));finish();break;}}private class PlayerProxy implements IPlayer{private IBinder ib;private String mStatus;public PlayerProxy(IBinder ib) {super();this.ib = ib;}public void play() {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeString("playing");try {ib.transact(1, data, reply, 0);mStatus = reply.readString();} catch (RemoteException e) {e.printStackTrace();}}public void stop() {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeString("stop");try {ib.transact(2, data, reply, 0);mStatus = reply.readString();} catch (RemoteException e) {e.printStackTrace();}}public String getStatus() {return mStatus;}}}