无效果无真相,先上图,以下为Service App和Client App两App间的跨进程通信
AIDL实现两应用通信
在main路径下新建AIDL文件
// IMsgReceiveListener.aidl
package com.scash.aidlservice;
// Declare any non-default types here with import statements
//用于接收两App的消息接口回调
import com.scash.aidlservice.Msg;//导入要传输对象的包
interface IMsgReceiveListener {
void onReceiveMsg(in Msg msg);
}
// IMsgManagerListener.aidl
package com.scash.aidlservice;
// Declare any non-default types here with import statements
import com.scash.aidlservice.Msg;//导入要传输对象的包
import com.scash.aidlservice.IMsgReceiveListener;
interface IMsgManagerListener {
void sendMsg(in Msg msg);
void registerListener(IMsgReceiveListener receiveListener);
void unRegisterListener(IMsgReceiveListener receiveListener);
}
// Msg.aidl
package com.scash.aidlservice;
// Declare any non-default types here with import statements
parcelable Msg;
package com.scash.aidlservice;
import android.os.Parcel;
import android.os.Parcelable;
/**
* @create 2022/6/17
* @Describe AIDL 传输对象时,只能传输实现Parcelable接口的对象
*/
public class Msg implements Parcelable {
private String msg;
private String type;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
protected Msg(Parcel in) {
msg = in.readString();
type = in.readString();
}
public static final Creator<Msg> CREATOR = new Creator<Msg>() {
@Override
public Msg createFromParcel(Parcel in) {
return new Msg(in);
}
@Override
public Msg[] newArray(int size) {
return new Msg[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(msg);
dest.writeString(type);
}
}
package com.scash.aidlservice
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.os.RemoteCallbackList
import android.util.Log
/**
* @create 2022/6/17
* @Describe
*/
open class RemotoService : Service() {
//AIDL不支持正常的接口回调,使用RemoteCallbackList实现接口回调
val mReceiveListener: RemoteCallbackList<IMsgReceiveListener> =
RemoteCallbackList<IMsgReceiveListener>()
override fun onBind(intent: Intent?): IBinder? {
return iBinder
}
val iBinder = object : IMsgManagerListener.Stub() {
override fun sendMsg(msg: Msg?) {
msg?.let { receiveMsg(it) }
}
override fun registerListener(receiveListener: IMsgReceiveListener?) {
mReceiveListener.register(receiveListener)
}
override fun unRegisterListener(receiveListener: IMsgReceiveListener?) {
val success = mReceiveListener.unregister(receiveListener)
Log.i("Ljw", "注册是否成功:$success")
}
}
fun receiveMsg(message: Msg) {
//通知Callback循环开始,返回N为实现mReceiveListener回调的个数
var Num = mReceiveListener.beginBroadcast()
message.msg = message.msg
repeat(Num) {
val listener: IMsgReceiveListener = mReceiveListener.getBroadcastItem(it)
listener.onReceiveMsg(message)
}
//通知通知Callback循环结束
mReceiveListener.finishBroadcast()
}
}
注册Service
<service
android:name=".RemotoService"
android:exported="true" />
/**
* @create 2022/6/23
* @Describe
*/
class MsgAdapter(val context: Context, val mList: List<Msg>) :
RecyclerView.Adapter<MsgAdapter.MyViewHolder>() {
inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val mTvMsg :TextView= view.findViewById(R.id.tv_msg)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(context)
.inflate(R.layout.item_msg, parent, false)
return MyViewHolder(view)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val mSimpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
(mSimpleDateFormat.format(Date(mList[position].date)) + mList[position].msg).also {
holder.mTvMsg.text = it
}
}
override fun getItemCount(): Int {
return mList.size
}
}
class MainActivity : AppCompatActivity(), View.OnClickListener {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
var binder: MyBinder? = null
var mManagerListener: IMsgManagerListener? = null
var msgAdapter: MsgAdapter? = null
var mList: ArrayList<Msg> = ArrayList()
var mBtnClickStamp: Long = 0//记录按键点击的时间戳
var mMsg = Msg()
val mHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == 1) {
msgAdapter?.notifyDataSetChanged()
binding.rvClient.smoothScrollToPosition(mList.size - 1)
}
}
}
var mConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
binder = iBinder as MyBinder
mManagerListener = IMsgManagerListener.Stub.asInterface(iBinder)
mManagerListener?.registerListener(mReceiveListener)
}
override fun onServiceDisconnected(name: ComponentName?) {
TODO("Not yet implemented")
}
}
val mReceiveListener = object : IMsgReceiveListener.Stub() {
override fun onReceiveMsg(msg: Msg?) {
if (IMsgType.CLIENT == msg?.type) {
msg.date = System.currentTimeMillis()
mList.add(msg)
mHandler.sendEmptyMessage(1)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
var intent = Intent(this, RemotoService::class.java)
bindService(intent, mConnection, BIND_AUTO_CREATE)
msgAdapter = MsgAdapter(this, mList)
binding.rvClient.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rvClient.adapter = msgAdapter
binding.btnSend.setOnClickListener(this)
}
override fun onDestroy() {
super.onDestroy()
mManagerListener?.unRegisterListener(mReceiveListener)
unbindService(mConnection)
}
fun isBtnBuffering(): Boolean {
var duration = System.currentTimeMillis() - mBtnClickStamp
mBtnClickStamp = System.currentTimeMillis()//记录点击时间
return Math.abs(duration) <= 400
}
override fun onClick(v: View?) {
if (isBtnBuffering()) {
return
}
if (TextUtils.isEmpty(binding.etSendMsg.text.toString())) {
Toast.makeText(this, "不能发送空数据", Toast.LENGTH_SHORT).show()
}
mMsg.msg = binding.etSendMsg.text.toString()
mMsg.type = IMsgType.SERVICE
binder?.sendMsg(mMsg)
}
}
/**
* @create 2022/6/17
* @Describe AIDL 传输对象时,只能传输实现Parcelable接口的对象
*/
public class Msg implements Parcelable {
private String msg;
private String type;
private long date;
public Msg() {
}
public Msg(String msg, String type) {
this.msg = msg;
this.type = type;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
protected Msg(Parcel in) {
msg = in.readString();
type = in.readString();
}
public static final Creator<Msg> CREATOR = new Creator<Msg>() {
@Override
public Msg createFromParcel(Parcel in) {
return new Msg(in);
}
@Override
public Msg[] newArray(int size) {
return new Msg[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(msg);
dest.writeString(type);
}
}
/**
* @create 2022/6/22
* @Describe
*/
class MsgAdapter(val context: Context, val mList: List<Msg>) :
RecyclerView.Adapter<MsgAdapter.MyViewHolder>() {
inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvMsg: TextView = view.findViewById(R.id.tv_msg)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(context)
.inflate(R.layout.item_msg, parent, false)
return MyViewHolder(view)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val mSimpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
(mSimpleDateFormat.format(Date(mList[position].date)) + mList[position].msg).also {
holder.tvMsg.text = it
}
}
override fun getItemCount(): Int {
return mList.size
}
}
class MainActivity : AppCompatActivity() {
val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
var mMsgManger: IMsgManagerListener? = null//定义AIDL
var myBinder: IMsgManagerListener? = null//定义AIDL
var mAdapter: MsgAdapter? = null
val mList = ArrayList<Msg>()
val mHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == 1) {
mAdapter?.notifyDataSetChanged()
binding.rvItem.smoothScrollToPosition(mList.size - 1)
}
}
}
var mReceiverMsgListener = object : IMsgReceiveListener.Stub() {
override fun onReceiveMsg(msg: Msg?) {
if (IMsgType.SERVICE == msg?.type) {
msg.date=System.currentTimeMillis()
mList.add(msg)
mHandler.sendEmptyMessage(1)
}
}
}
var mConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) {
myBinder = IMsgManagerListener.Stub.asInterface(iBinder);
mMsgManger = IMsgManagerListener.Stub.asInterface(iBinder)
//链接到死亡代理
mMsgManger?.asBinder()?.linkToDeath(mDeathRecipient, 0)
//注册监听
mMsgManger?.registerListener(mReceiverMsgListener)
}
override fun onServiceDisconnected(name: ComponentName?) {
}
}
var mDeathRecipient = object : IBinder.DeathRecipient {
override fun binderDied() {
if (mMsgManger == null) {
return
}
mMsgManger!!.asBinder().unlinkToDeath(this, 0)
mMsgManger = null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val intent = Intent()
intent.action = "com.scash.aidlservice.RemotoService"
intent.`package` = "com.scash.aidlservice"
bindService(intent, mConnection, BIND_AUTO_CREATE)
mAdapter = MsgAdapter(this, mList)
binding.rvItem.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL,false)
binding.rvItem.adapter = mAdapter
val btn: Button = findViewById(R.id.btn_client_send)
btn.setOnClickListener {
val mMsg = Msg()
mMsg.msg = binding.etSendMsgTest.text.toString()
mMsg.type = IMsgType.CLIENT
mMsgManger?.sendMsg(mMsg)
}
// binding.btnClientSend.setOnClickListener {
// mMsgManger?.sendMsg(mMsg)
// }
}
override fun onDestroy() {
super.onDestroy()
unbindService(mConnection)
mMsgManger?.unRegisterListener(mReceiverMsgListener)
}
}