欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AIDL 服务端给客户端发消息

程序员文章站 2022-05-21 13:44:12
...

1.源码示例

https://github.com/sufadi/AndroidCpuTools

代码清单
D:\AndroidStudioProject\CpuRun\app\src\main\aidl\com\fadisu\cpurun\service\ICpuMsgCallBack.aidl
D:\AndroidStudioProject\CpuRun\app\src\main\aidl\com\fadisu\cpurun\service\ICpuMsgService.aidl
D:\AndroidStudioProject\CpuRun\app\src\main\java\com\fadisu\cpurun\fragment\CpuStatusFragment.java
D:\AndroidStudioProject\CpuRun\app\src\main\java\com\fadisu\cpurun\service\CpuMsgService.java
D:\AndroidStudioProject\CpuRun\app\src\main\AndroidManifest.xml

2.AIDL 接口

D:\AndroidStudioProject\CpuRun\app\src\main\aidl\com\fadisu\cpurun\service\ICpuMsgCallBack.aidl

D:\AndroidStudioProject\CpuRun\app\src\main\aidl\com\fadisu\cpurun\service\ICpuMsgService.aidl

ICpuMsgCallBack 回调接口

package com.fadisu.cpurun.service;

import java.util.List;

interface ICpuMsgCallBack {
    void updateCpuUsage(in List<String> msg);
}

ICpuMsgService 注册和注销接口

package com.fadisu.cpurun.service;

import com.fadisu.cpurun.service.ICpuMsgCallBack;
import java.util.List;

interface ICpuMsgService {

    void registerCallback(ICpuMsgCallBack cb);

    void unregisterCallback(ICpuMsgCallBack cb);

    void updateCpuUsage(in List<String> msg);
}

3.AIDL 服务端

D:\AndroidStudioProject\CpuRun\app\src\main\java\com\fadisu\cpurun\service\CpuMsgService.java

D:\AndroidStudioProject\CpuRun\app\src\main\AndroidManifest.xml

AndroidManifest.xml 注册服务

        <service android:name="com.fadisu.cpurun.service.CpuMsgService"></service>

CpuMsgService.java

服务端主要实现 onBind 的重写,完成 AIDL 绑定接口,然后在调用接口发送数据给客户端


package com.fadisu.cpurun.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import com.fadisu.cpurun.R;
import com.fadisu.cpurun.util.CpuUtils;
import com.fadisu.cpurun.util.ProcCpuStatUtil;

import java.util.ArrayList;
import java.util.List;

public class CpuMsgService extends Service {

    public static final String ACTION_CPU_USAGE_START = "action_cpu_usage_start";
    public static final String ACTION_CPU_USAGE_END = "action_cpu_usage_end";
    private boolean isRun;
    private Thread mThread;
    private Context mContext;
    private ICpuMsgService mICpuMsgService = new MyICpuMsgService();
    private final RemoteCallbackList<ICpuMsgCallBack> mCallbackList = new RemoteCallbackList<ICpuMsgCallBack>();


    @Override
    public IBinder onBind(Intent intent) {
        return (IBinder) mICpuMsgService;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        isRun = true;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (null == intent) {
            return super.onStartCommand(intent, flags, startId);
        }

        String action = intent.getAction();
        if (null == action) {
            return super.onStartCommand(intent, flags, startId);
        }

        if (ACTION_CPU_USAGE_START.equals(action)) {
            Log.d("CpuMsgService", "startTask");
            startTask();
        } else if (ACTION_CPU_USAGE_END.equals(action)) {
            Log.d("CpuMsgService", "stopTask");
            stopTask();
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        stopTask();
        super.onDestroy();
    }

    private void startTask() {
        if (null != mThread) {
            return;
        }
        isRun = true;
        mThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (isRun) {
                    List<String> result = new ArrayList<>();
                    result.add(mContext.getString(R.string.cpu_usage) + ProcCpuStatUtil.getCpuUsage());
                    result.addAll(CpuUtils.getCpuCurFreq(mContext));
                    if (null != mICpuMsgService) {
                        try {
                            Log.d("CpuMsgService", "getCpuUsage = " + result.get(0));
                            mICpuMsgService.updateCpuUsage(result);
                        } catch (RemoteException e) {
                            //e.printStackTrace();
                        }
                    }
                }
            }
        });

        mThread.start();
    }

    private void stopTask() {
        isRun = false;

        if (mThread != null) {
            mThread.interrupt();
            mThread = null;
        }
    }

    class MyICpuMsgService extends ICpuMsgService.Stub {

        @Override
        public void registerCallback(ICpuMsgCallBack cb) throws RemoteException {
            if (cb != null) {
                mCallbackList.register(cb);
            }
        }

        @Override
        public void unregisterCallback(ICpuMsgCallBack cb) throws RemoteException {
            if (cb != null) {
                mCallbackList.unregister(cb);
            }
        }

        @Override
        public void updateCpuUsage(List<String> msg) throws RemoteException {
            final int N = mCallbackList.beginBroadcast();
            for (int i = 0; i < N; i++) {
                try {
                    mCallbackList.getBroadcastItem(i).updateCpuUsage(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            mCallbackList.finishBroadcast();
        }
    }
}

4.AIDL 客户端

D:\AndroidStudioProject\CpuRun\app\src\main\java\com\fadisu\cpurun\fragment\CpuStatusFragment.java

客户端 bingService就可以监听服务端的消息数据了,并在 updateCpuUsage ()刷新数据

package com.fadisu.cpurun.fragment;

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.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

import com.fadisu.cpurun.R;
import com.fadisu.cpurun.adapter.CustomAdapter;
import com.fadisu.cpurun.service.CpuMsgService;
import com.fadisu.cpurun.service.ICpuMsgCallBack;
import com.fadisu.cpurun.service.ICpuMsgService;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;


public class CpuStatusFragment extends Fragment implements CustomAdapter.LayoutView {

    public static final int UPDATE_UI = 0;

    private Context mContext;
    private List<String> result;
    private CustomAdapter<String> mCustomAdapter;

    private View mView;
    private ListView mListView;

    private Handler mHandler = null;
    private ICpuMsgCallBack mICpuMsgCallBack = new ICpuMsgCallBack.Stub() {

        @Override
        public void updateCpuUsage(List<String> list) throws RemoteException {
            if (null != list) {
                result.clear();
                result.addAll(list);
                mHandler.sendEmptyMessage(UPDATE_UI);
            }
        }
    };

    ;
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            try {
                ICpuMsgService mICpuMsgService = ICpuMsgService.Stub.asInterface(iBinder);
                mICpuMsgService.registerCallback(mICpuMsgCallBack);
                Log.d("CpuMsgService", "onServiceConnected");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d("CpuMsgService", "onServiceDisconnected");
        }
    };

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_base, container, false);
        initViews();
        initValues();
        initListeners();
        return mView;
    }

    @Override
    public void onResume() {
        bindService();
        super.onResume();
    }

    @Override
    public void onStop() {
        unBindService();
        super.onStop();
    }

    private void initViews() {
        mListView = (ListView) mView.findViewById(R.id.listview);
    }

    private void initValues() {
        mHandler = new MyHandler(this);
        result = new ArrayList<>();
        result.add("ServiceConnection .....");
        mCustomAdapter = new CustomAdapter<String>(result);
        mListView.setAdapter(mCustomAdapter);
        mHandler.sendEmptyMessage(UPDATE_UI);
    }

    private void initListeners() {
        mCustomAdapter.setLayoutView(this);
    }

    @Override
    public <T> View setView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_base, null);
            holder = new ViewHolder();
            convertView.setTag(holder);

            holder.tv_info = (TextView) convertView.findViewById(R.id.tv_info);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tv_info.setText(result.get(position));

        return convertView;
    }

    private void bindService() {
        Intent intent = new Intent(mContext, CpuMsgService.class);
        intent.setAction(CpuMsgService.ACTION_CPU_USAGE_START);
        mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        Log.d("CpuMsgService", "bindService");
    }

    private void unBindService() {
        Intent intent = new Intent(mContext, CpuMsgService.class);
        intent.setAction(CpuMsgService.ACTION_CPU_USAGE_START);
        mContext.unbindService(mConnection);
        Log.d("CpuMsgService", "unBindService");
    }

    private static class MyHandler extends Handler {

        WeakReference<CpuStatusFragment> mActivity;

        public MyHandler(CpuStatusFragment activity) {
            mActivity = new WeakReference<CpuStatusFragment>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            CpuStatusFragment activity = mActivity.get();
            switch (msg.what) {
                case UPDATE_UI:
                    activity.mCustomAdapter.updateData((ArrayList<String>) activity.result);
                    break;
                default:
                    break;
            }
        }
    }

    class ViewHolder {
        TextView tv_info;
    }
}

4.UI显示

AIDL 服务端给客户端发消息