前言
aidl全称是android interface definition language即安卓接口定义语言。只要是提供给不同进程间的通讯作用,开发中使用还是挺多的,在此本人就编写个类似开启下载服务回调的方式的demo。项目框架:app为其中的一个可以提供给外面第三方应用调用开启下载服务的一个应用,clientApp即类似第三方需要调用该下载服务的一个应用,servicelib为下载服务的lib包,aidllib为提供给外面引用关联改servicelib调用里面的服务函数(测试、开启和设置监听回调等方法)。
项目结构图
运行效果图
第三方app调用图
代码
aidllib jar包下的文件
相关代码
IService.aidl:
// IService.aidl
package com.example.lainanzhou.aidllib;
// Declare any non-default types here with import statements
import com.example.lainanzhou.aidllib.IServiceListener;
import com.example.lainanzhou.aidllib.IListener;
import com.example.lainanzhou.aidllib.Task;
interface IService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void test();// 测试直接调用aidl方法
void start(in Task task,IServiceListener iServiceListener);// 方法里面携带监听回调对象
void setListener(IListener listener);// 设置监听
}
IServiceListener.aidl:
// IServiceListener.aidl
package com.example.lainanzhou.aidllib;
// Declare any non-default types here with import statements
interface IServiceListener {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void download(int progress);
void cancel();
}
IListener.aidl:
// P2PTask.aidl
package com.example.lainanzhou.aidllib;
// Declare any non-default types here with import statements
interface IListener{
void callback();
}
// Task.aidl.aidl
package com.example.lainanzhou.aidllib;
// Declare any non-default types here with import statements
parcelable Task;
package com.example.lainanzhou.aidllib;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 任务bean
*
* @author zhou
* @since 2016/10/21
*/
public class Task implements Parcelable {
private int id;
private Params params;
private List<IServiceListener> mListenerList = new CopyOnWriteArrayList<>();
public Task() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Params getParams() {
return params;
}
public void setParams(Params params) {
this.params = params;
}
public List<IServiceListener> getmListenerList() {
return mListenerList;
}
public void setmListenerList(List<IServiceListener> mListenerList) {
this.mListenerList = mListenerList;
}
public void addListener(IServiceListener listener) {
if (listener != null && !mListenerList.contains(listener)) {
mListenerList.add(listener);
}
}
public void download(int progress) {
for (IServiceListener listener : mListenerList) {
try {
listener.download(progress);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public void cancel() {
for (IServiceListener listener : mListenerList) {
try {
listener.cancel();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
protected Task(Parcel in) {
id = in.readInt();
params = in.readParcelable(Params.class.getClassLoader());
mListenerList = in.readArrayList(IServiceListener.class.getClassLoader());
}
public static final Creator<Task> CREATOR = new Creator<Task>() {
@Override
public Task createFromParcel(Parcel in) {
return new Task(in);
}
@Override
public Task[] newArray(int size) {
return new Task[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeParcelable(params, i);
parcel.writeList(mListenerList);
}
@Override
public String toString() {
return "Task{" +
"id=" + id +
", params=" + params.toString() +
", mListenerList=" + mListenerList +
'}';
}
}
Params.aidl:
// Task.aidl.aidl
package com.example.lainanzhou.aidllib;
// Declare any non-default types here with import statements
parcelable Params;
Params.java:
package com.example.lainanzhou.aidllib;
import android.os.Parcel;
import android.os.Parcelable;
/**
* @author zhou
* @since 2016/10/21
*/
public class Params implements Parcelable {
private String url;
private int versionCode;
public Params(String url, int versionCode) {
this.url = url;
this.versionCode = versionCode;
}
protected Params(Parcel in) {
url = in.readString();
versionCode = in.readInt();
}
public static final Creator<Params> CREATOR = new Creator<Params>() {
@Override
public Params createFromParcel(Parcel in) {
return new Params(in);
}
@Override
public Params[] newArray(int size) {
return new Params[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(url);
parcel.writeInt(versionCode);
}
@Override
public String toString() {
return "Params{" +
"url='" + url + '\'' +
", versionCode=" + versionCode +
'}';
}
}
servicelib jar包: 需要引入aidllib依赖包
ServiceDemo.java 代码:
package com.example.lainanzhou.servicelib;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import com.example.lainanzhou.aidllib.IListener;
import com.example.lainanzhou.aidllib.IService;
import com.example.lainanzhou.aidllib.IServiceListener;
import com.example.lainanzhou.aidllib.Task;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 提供给外界调用的service
*
* @author zhou
* @since 2016/10/21
*/
public class ServiceDemo extends Service {
private static final String TAG = "ServiceDemo";
private List<IListener> listenerList = new CopyOnWriteArrayList<>();
private Map<Integer, Integer> progressMap = new HashMap<>();
private Timer timer = new Timer();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
/**
* 连接的binder对象,并将结果返回给调用者
*/
private IBinder binder = new IService.Stub() {
@Override
public void test() throws RemoteException {
Log.d(TAG, "test");
}
@Override
public void start(Task task, IServiceListener iServiceListener) throws RemoteException {
Log.d(TAG, "start: " + task.toString());
task.addListener(iServiceListener);
if (!progressMap.containsKey(task.getId())) {
progressMap.put(task.getId(), 0);
startTimer(task);
}
}
@Override
public void setListener(IListener listener) throws RemoteException {
Log.d(TAG, "setListener");
if (listener != null && !listenerList.contains(listener)) {
listenerList.add(listener);
}
}
};
private void startTimer(final Task task) {
Log.d(TAG, "startTimer");
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
int progress = progressMap.get(task.getId());
progressMap.put(task.getId(), ++progress);
progress = progressMap.get(task.getId());
task.download(progress);
if (progress >= 100) {
Log.d(TAG, "cancel");
task.cancel();
for (IListener listener : listenerList) {
try {
listener.callback();
} catch (RemoteException e) {
e.printStackTrace();
}
}
timer.cancel();
}
}
};
timer.schedule(timerTask, 0, 1000);
}
}
主程序app
MainActivity.java代码:需要引入servicelib依赖包
package com.example.lainanzhou.aidldemo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.example.lainanzhou.aidllib.IService;
import com.example.lainanzhou.aidllib.IServiceListener;
import com.example.lainanzhou.aidllib.Params;
import com.example.lainanzhou.aidllib.Task;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "App";
private IService mService;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ServiceConnection conn = new ServiceConnection() {
// 连接成功
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mService = IService.Stub.asInterface(iBinder);
Log.d(TAG, "onServiceConnected: " + (mService != null));
}
// 连接失败
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected");
}
};
public void binder(View view) {
Log.d(TAG, "binder");
if (intent == null) {
intent = new Intent();
intent.setAction("com.example.lainanzhou.servicelib.bindServiceDemo");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
}
public void unBinder(View view) {
if (intent != null) {
unbindService(conn);
intent = null;
mService = null;
}
}
public void test(View view) {
if (mService == null) return;
try {
mService.test();
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void start(View v) {
if (mService == null) return;
Task task = new Task();
task.setId(0);
Params params = new Params("www.0.com", 0);
task.setParams(params);
try {
mService.start(task, new IServiceListener.Stub() {
@Override
public void download(int progress) throws RemoteException {
Log.d(TAG, "download: " + progress);
}
@Override
public void cancel() throws RemoteException {
Log.d(TAG, "cancel");
}
});
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
第三方调用该服务的clientApp: 需要引入aidllib依赖包
MainActivity.java代码:
package com.example.lainanzhou.clientapp;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.example.lainanzhou.aidllib.IService;
import com.example.lainanzhou.aidllib.IServiceListener;
import com.example.lainanzhou.aidllib.Params;
import com.example.lainanzhou.aidllib.Task;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "clientApp";
private IService mService;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ServiceConnection conn = new ServiceConnection() {
// 连接成功
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mService = IService.Stub.asInterface(iBinder);
Log.d(TAG, "onServiceConnected: " + (mService != null));
}
// 连接失败
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected");
}
};
public void binder(View view) {
Log.d(TAG, "binder");
if (intent == null) {
intent = new Intent();
intent.setAction("com.example.lainanzhou.servicelib.bindServiceDemo");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
}
public void unBinder(View view) {
if (intent != null) {
unbindService(conn);
intent = null;
mService = null;
}
}
public void test(View view) {
if (mService == null) return;
try {
mService.test();
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void start(View v) {
if (mService == null) return;
Task task = new Task();
task.setId(1);
Params params = new Params("www.1.com", 1);
task.setParams(params);
try {
mService.start(task, new IServiceListener.Stub() {
@Override
public void download(int progress) throws RemoteException {
Log.d(TAG, "download: " + progress);
}
@Override
public void cancel() throws RemoteException {
Log.d(TAG, "cancel");
}
});
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
注意:
1. 传递的对象需要继承Parcelable并实现相应的方法。
2. 传递的接口需要定义为.aidl文件方式转binder对象传递,并定义为interface。
3. 传递的对象需要创建对应的类型.aidl文件,并定义为parcelable。
4. IService.aidl文件里面需要自行输入import xxx.xxx.xxx.对象 ,即自行导入对象和接口。
5. 最后注意包名要一致。
源代码链接:点击打开链接