Android AIDL学习(二)

来源:互联网 发布:阿里云盾占用80端口 编辑:程序博客网 时间:2024/05/22 12:28

Android AIDL学习(二)

本文主要写在同一个module中如何使用不同进程的服务。

  1. 在测试机的/mnt/sdcard/路径下放一首mp3格式的音乐文件,故音乐文件的路径为/mnt/sdcard/music.mp3。
  2. 新建项目,使用默认module,在moudle下新建AIDL文件夹,创建一个AIDL文件IPlayServiceAIDL.aidl,并在文件中添加play()与stop()方法,aidl文件中不可使用private,protected,public等关键词,但返回值要标明,创建好之后点击build->make project来编译工程。
package com.mazaiting.aidldemo2;interface IPlayServiceAIDL {    void play();    void stop();    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);}
  1. 在项目的java目录下创建PlayService.java类,并继承Service。在PlayService中的onBind方法中返回一个IBinder对象,这个对象可new IPlayServiceAIDL.Stub()来得到,并实现其中的方法,如果哪个方法你不需要,则可以不实现它。
public class PlayService extends Service {  private MediaPlayer mediaPlayer;  public PlayService() {  }  @Override public IBinder onBind(Intent intent) {    try{      mediaPlayer = new MediaPlayer();      String path = Environment.getExternalStorageDirectory()+"/music.mp3";      File file = new File(path);      FileInputStream fis = new FileInputStream(file);      mediaPlayer.setDataSource(fis.getFD());      mediaPlayer.setLooping(true);    }catch (Exception e){      e.printStackTrace();    }    return mBinder;  }  private IBinder mBinder = new IPlayServiceAIDL.Stub(){    @Override public void play() throws RemoteException {      if (mediaPlayer.isPlaying()){        return;      }      mediaPlayer.prepareAsync();      mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {        @Override public void onPrepared(MediaPlayer mp) {          mediaPlayer.start();        }      });    }    @Override public void stop() throws RemoteException {      if (mediaPlayer.isPlaying()){        mediaPlayer.stop();      }    }    @Override    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble,        String aString) throws RemoteException {    }  };}
  1. 接下来在AndroidManifest.xml文件中对PlayService进行配置,首先先配置一个访问内存卡的权限,其次在service节点内配置android:process=":remote",此语句表示运行在remote进程中,最后在service节点下配置intent-filter,并在intent-filter中配置action,action的name属性就配置为PlayService的包名+类型。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  <application      android:allowBackup="true"      android:icon="@mipmap/ic_launcher"      android:label="@string/app_name"      android:supportsRtl="true"      android:theme="@style/AppTheme">    <activity android:name=".MainActivity">      <intent-filter>        <action android:name="android.intent.action.MAIN" />        <category android:name="android.intent.category.LAUNCHER" />      </intent-filter>    </activity>    <service        android:name=".PlayService"        android:enabled="true"        android:exported="true"        android:process=":remote">      <intent-filter>        <action android:name="com.mazaiting.aidldemo2.PlayService" />      </intent-filter>    </service>  </application>
  1. 简单的编写MainActivity.java的布局文件,两个水平排列的按钮,一个用于播放音乐,一个用于暂停播放。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"    >  <Button      android:id="@+id/btn_start"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="start"      />  <Button      android:id="@+id/btn_stop"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="stop"      /></LinearLayout>
  1. 接下来实现MainActivity.java中的代码,按钮的初始化及设置点击事件不再赘述,在onResume方法中调用bindService对服务进行绑定, 此方法有三个参数,第一个参数为Intent,并为其设置Action,第二个参数为ServiceConnection对象,方法中用于获得AIDL远程调用的对象,第三个方法参数为一个int值,一般设置它为 Context.BIND_AUTO_CREATE。在onPause方法中调用unbindService对绑定的服务进行解绑。点击按钮时分别调用start,stop方法来控制音乐的播放与暂停。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {  private static final String ACTION = "com.mazaiting.aidldemo2.PlayService";  private Button btnStart,btnStop;  private IPlayServiceAIDL mBinder;  private ServiceConnection mConncet = new ServiceConnection() {    @Override public void onServiceConnected(ComponentName name, IBinder service) {      mBinder = IPlayServiceAIDL.Stub.asInterface(service);    }    @Override public void onServiceDisconnected(ComponentName name) {      mBinder = null;    }  };  @Override protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initView();  }  @Override protected void onResume() {    super.onResume();    Intent service = new Intent(ACTION);    bindService(service,mConncet, Context.BIND_AUTO_CREATE);  }  @Override protected void onPause() {    super.onPause();    unbindService(mConncet);  }  private void initView() {    btnStart = (Button) findViewById(R.id.btn_start);    btnStop = (Button) findViewById(R.id.btn_stop);    btnStart.setOnClickListener(this);    btnStop.setOnClickListener(this);  }  @Override public void onClick(View v) {    switch (v.getId()){      case R.id.btn_start:        try {          mBinder.play();        } catch (RemoteException e) {          e.printStackTrace();        }        break;      case R.id.btn_stop:        try {          mBinder.stop();        } catch (RemoteException e) {          e.printStackTrace();        }        break;    }  }}