在学到Service时就想过怎么对操作服务里的一些方法,通过网上学习到了AIDL能对服务进行控制,写下自己的见解。
AIDL是Android 的接口定义语言(Interface Definition Language),能实现,因为安卓的其他三个组件都能跨进程通信,所以服务也可以通过它来通信。
我是以一个播放音乐的例子来说明他的作用,我们会让音乐在服务中启动,因为他不会应为Activity的销毁而销毁,服务的优先级高。例子中我要实现能控制服务中的音乐中的音乐的播放和暂停。代码我是在Android Studio中实现
1.先创建一个AIDL文件,如图
它就会生成一个文件夹aidl,文件夹下有个包里就有我们创建的AIDL文件,图上能看见。
2.音乐的播放和暂停需要两个方法控制,start,和stop在接口(AIDL文件)中写出两个方法(多的那个add(方法是我测试用的,可以忽略))
AIDL代码如下
名字我取得IMyInt.aidl
// IMyInt.aidl
package com.example.administrator.aidldemo;
// Declare any non-default types here with import statements
interface IMyInt {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String add();
void start();
void stop();
}
3.服务中要实现这个接口(AIDL文件)的方法
Service代码:
package com.example.administrator.aidldemo;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class MyService extends Service {
MediaPlayer mediaPlayer; //?
int MusicProgress=0;
IMyInt.Stub myInt=new IMyInt.Stub() {
@Override
public String add() throws RemoteException {
return "AIDL";
}
@Override
public void start() throws RemoteException {
mediaPlayer=MediaPlayer.create(getApplicationContext(),Uri.parse("/sdcard/Download/1st_spine.ogg"));
mediaPlayer.start();
mediaPlayer.seekTo(MusicProgress);
}
@Override
public void stop() throws RemoteException {
MusicProgress=mediaPlayer.getCurrentPosition();
mediaPlayer.stop();
}
};
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.i("aa","bind");
return myInt; //返回
}
}
定义的IMyInt.Stub是继承了IBinder 实现我们定义的AIDL接口。将接口中的方法实现,对音乐的播放暂停进行控制。
在onBind方法中返回我们定义的MyInt.
音乐我选的是我SD卡中的,可以自己更改路径和文件。
4.在主文件中绑定服务,控制服务中的播放和暂停,代码如下
package com.example.administrator.aidldemo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
IMyInt Add; //定义接口
String result;
TextView textView;
Button btn_add,btn_start,btn_stop;
ServiceConnection serviceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Add=IMyInt.Stub.asInterface(service); //
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_add= (Button) findViewById(R.id.btn_add);
btn_start= (Button) findViewById(R.id.btn_start);
btn_stop= (Button) findViewById(R.id.btn_stop);
textView= (TextView) findViewById(R.id.tv);
bindService(new Intent(getApplicationContext(),MyService.class),serviceConnection,BIND_AUTO_CREATE);
btn_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
result=Add.add();
} catch (RemoteException e) {
e.printStackTrace();
}
textView.setText(result);
}
});
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Add.start();
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
btn_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Add.stop();
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
上面主要的是我们创建的服务连接对象,在成功连接后使用
IMyInt.Stub.asInterface(service)赋值给了我们定义的AIDL文件的对象
主布局文件如下
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.administrator.aidldemo.MainActivity"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:id="@+id/btn_add" android:layout_below="@id/tv" android:text="计算" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:layout_below="@id/btn_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放" android:id="@+id/btn_start"/> <Button android:layout_below="@id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暂停" android:id="@+id/btn_stop"/> </RelativeLayout>
实际效果
模拟器上会有声音,我也加入了进度的延续,别忘了读取外部存储加入权限。