(原创)使用aidl进程间通讯并开启独立进程的服务仿下载监听回调等场景

前言

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();
}

T ask.aidl:
// Task.aidl.aidl
package com.example.lainanzhou.aidllib;

// Declare any non-default types here with import statements

parcelable Task;

Task.java:
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. 最后注意包名要一致。

源代码链接:点击打开链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值