Android AIDL和远程Service调用

第一、我们知道在AndroId中如果需要进行音乐播放,最方面的方法就是使用自带的MediaPlayer对象,如果我们在Activity中控制MediaPlayer对象进行播放,那么一旦你打开了另外一个程序譬如浏览器,那么歌声就会立刻停止,这当然不是我们需要的结果。 我们需要的是在做其他事情的同时能够在后台听歌,于是我们就需要把对MediaPlayer对象的操作放在后台Service中去。

第二、我们已经把对MediaPlayer的操作转移到Service中去了,按照我们以前的做法,我们在Activity中发送一个Intent对象给Service对象,在Intent中传送播放啊、暂停啊一类的信息给Service,这样Service就知道该怎么做了。这一切看起来很美好,可是现在出了一个新问题,那就是我想在Activity中显示一个进度条,这个进度条要跟着Service中的MediaPlayer中的歌曲进度同步向前走,而且如果我点击进度条中的某一个位置,还想让歌曲跳转到新的时间点继续播放,这个,该怎么实现?

第三、我们需要在Activity中操作Service中的MediaPlayer对象,就好像这个对象是自己的一样。我们可以采用Android接口定义语言 AIDL(Android Interface Definition Language)技术:

1、把Service中针对MediaPlayer的操作封装成一个接口(.aidl文件)
2、在Service中建个子类实现这接口的存根(stub)对象
3、并在onBind()方法中返回这个存根对象。
4、在Activity中使用绑定服务的方式连接Service,但是不用Intent来传递信息,而是在ServiceConnection的onServiceConnected方法里,获得Service中Stub对象的客户端使用代理。我们通过操作Activity中的代理就可以达到操作Service中的MediaPlayer对象的目的。这样我们就可以想用本地对象一样操作Service中的对象了,那么进度条一类的需求自然也就迎刃而解。

1、新建一个项目 App_elfPlayer ,启动Activity是个启动画面:CoverActivity
2、AndroidManifest.xml 的内容如下:

java代码:

<?xml version="1.0" encoding="utf-8"?>    <MANIFEST android:versionname="1.0" android:versioncode="1" xmlns:android=http://schemas.android.com/apk/res/android"package="eoe.demo">   <USES android:minsdkversion="7" -sdk /><USES android:name="android.permission.WRITE_EXTERNAL_STORAGE" -permission></USES><APPLICATION android:icon="@drawable/icon" android:label="@string/app_name"> <ACTIVITY android:name=".CoverActivity"> <INTENT -filter> <ACTION android:name="android.intent.action.MAIN" /> <CATEGORY android:name="android.intent.category.LAUNCHER" /> </INTENT> </ACTIVITY> <ACTIVITY android:name=".PlayerActivity"> </ACTIVITY> <SERVICE android:name=".MusicService" android:enabled="true"> </SERVICE> </APPLICATION> </MANIFEST>

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

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

java代码:

package eoe.demo; import android.app.Activity;  import android.content.Intent;  import android.os.Bundle;  import android.os.Handler;  import android.view.Window;  import android.view.WindowManager;    public class CoverActivity extends Activity {   /** Called when the activity is first created. */ @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);requestWindowFeature(Window.FEATURE_NO_TITLE);  setContentView(R.layout.cover);  new Handler().postDelayed(new Runnable(){  @Override  public void run() {  Intent mainIntent = new Intent(CoverActivity.this,PlayerActivity.class);  CoverActivity.this.startActivity(mainIntent);  CoverActivity.this.finish();  }  }, 2000);  } } 


4、PlayerActivity.java的代码如下:

java代码:

package eoe.demo; 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.Handler;import android.os.IBinder;import android.os.Message; import android.os.RemoteException;import android.util.Log;import android.view.View;import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener;public class PlayerActivity extends Activity {public static final int PLAY = 1; public static final int PAUSE = 2; ImageButton imageButtonFavorite; ImageButton imageButtonNext; ImageButton imageButtonPlay; ImageButton imageButtonPre; ImageButton imageButtonRepeat; SeekBar musicSeekBar; IServicePlayer iPlayer; boolean isPlaying = false; boolean isLoop = false;@Override  public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.player); imageButtonFavorite = (ImageButton) findViewById(R.id.imageButtonFavorite); imageButtonNext = (ImageButton) findViewById(R.id.imageButtonNext);imageButtonPlay = (ImageButton) findViewById(R.id.imageButtonPlay);imageButtonPre = (ImageButton) findViewById(R.id.imageButtonPre);imageButtonRepeat = (ImageButton) findViewById(R.id.imageButtonRepeat);musicSeekBar = (SeekBar) findViewById(R.id.musicSeekBar);bindService(new Intent(PlayerActivity.this, MusicService.class), conn, Context.BIND_AUTO_CREATE); startService(new Intent(PlayerActivity.this, MusicService.class));imageButtonPlay.setOnClickListener(new View.OnClickListener() {@Override  public void onClick(View v) {  Log.i("yao", "imageButtonPlay -> onClick");  if (!isPlaying) {  try {  iPlayer.play();  } catch (RemoteException e) {  e.printStackTrace();  }  imageButtonPlay.setBackgroundResource(R.drawable.pause_button);  isPlaying = true;  } else {  try {  iPlayer.pause();  } catch (RemoteException e) {  e.printStackTrace();  }  imageButtonPlay.setBackgroundResource(R.drawable.play_button);isPlaying = false;}}});  musicSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Override  public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {  } @Override  public void onStartTrackingTouch(SeekBar seekBar) {  } @Override  public void onStopTrackingTouch(SeekBar seekBar) {  if (iPlayer != null) {  try {  iPlayer.seekTo(seekBar.getProgress());  } catch (RemoteException e) {  e.printStackTrace();  }}}});  handler.post(updateThread);  }  private ServiceConnection conn = new ServiceConnection() {  public void onServiceConnected(ComponentName className, IBinder service) {  Log.i("yao", "ServiceConnection -> onServiceConnected");  iPlayer = IServicePlayer.Stub.asInterface(service);  } public void onServiceDisconnected(ComponentName className) {  };  };  Handler handler = new Handler() {@Override  public void handleMessage(Message msg) {  };  };  private Runnable updateThread = new Runnable() {  @Override  public void run() {  if (iPlayer != null) {  try {  musicSeekBar.setMax(iPlayer.getDuration());  musicSeekBar.setProgress(iPlayer.getCurrentPosition());  } catch (RemoteException e) {  e.printStackTrace();  }  }  handler.post(updateThread);  }  };  } 

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. android文档查询小工具
  3. ym—— Android(安卓)5.0学习之感想篇(含Demo)
  4. Android本地视频播放器开发--搜索本地视频(2)
  5. Android(安卓)MultiMedia框架完全解析 - 概览
  6. android实现软键盘弹出,editText随键盘上移,背景不动
  7. Android的Socket 通信
  8. Android菜鸟的成长笔记(5)——Android系统源代码你下载了吗?
  9. Android(安卓)SDK中的必会工具——ADB是真的香

随机推荐

  1. golang和哪种语言像?
  2. golang和nodejs的区别是什么?
  3. golang如何连接mysql
  4. golang如何读取文件
  5. golang和go语言有区别吗?
  6. golang如何封装路由
  7. golang和python的区别
  8. golang和c的区别是什么?
  9. golang如何防止意外崩溃
  10. golang可以写安卓吗