美文网首页
基于handler+Binder的Messenger

基于handler+Binder的Messenger

作者: 蜗牛是不是牛 | 来源:发表于2022-11-21 17:38 被阅读0次

Messenger是一种轻量级的IPC方案,底层实现了AIDL,只是进行了封装,开发的时候不用再写.aidl文件。通过了Handler消息机制进行的封装,所以取名了Messenger。也是因此,一次只能处理一个请求。此外,Messenger无法支持跨机器的IPC。

一、Messager用法概述:


Server端:
收到的请求放在Handler的MessageQueue里面,通过looper轮循,handler处理
Client端:
Client端要拿到返回值,需要把client的Messager作为msg.replyTO参数传递过去,Service端处理完之后,再调用客户端的Messenger的send(Message msg)方法吧返回值传递回client。

二、实现案例

2.1注册文件:

<service android:name=".MessengerServer">
    <intent-filter>
        <action android:name="android.intent.action.MESSENGER"/>
    </intent -filter>
</service>

2.2服务端:

public class MessengerServer extends Service{
    
    private static final int MSG_FROM_CLIENT = 0x10001;
    private static final int MSG_TO_CLIENT = 0x10002;
    private static final String IS_LOGIN = "isLogin";
    private static final String NICK_NAME = "nickName";
    private static final String USER_ID = "userId";
    
    @SuppressLint("HandlerLeak")
    private Messenger mMessenger = new Messenger(new Handler(){
        @Override
        public void handleMessage(Message msgfromClient){
        Message msgToClient = Message.obtain(msgfromClient);//返回给客户端的信息
        switch(msgfromClient.what){
                //msg 客户端传来的消息
                case MSG_FROM_CLIENT;
                try{
                    //模拟耗时
                    Thread.sleep(2000);
                    
                   //传递数据
                   Bundle toClicentDate = new Bundle();
                   toClicentDate.putString(NICK_NAME,"张小可");
                   toClicentDate.putBoolean(IS_LOGIN,true);
                   toClicentDate.putInt(USER_ID,10086);
                   msgToClient.setData(toClicentDate);
                   msgToClient.what = MSG_TO_CLIENT;
                    
                   //传回Client
                    msgfromClient.replyTo.send(msgToClient);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }catch(RemoteException e){
                    e.printStackTrace();
                }
                break;
        }
        super.handleMessage(msgfromClient);
    }
});
   
 @Nullable
 @Override
 public IBinder onBind(Intent intent){
     return mMessenger.getBinder();
  }
}

2.3客户端:

public class MainActivity extends AppCompatActivity {
    private TextView tv_style;
    private EditText et_accotun;
    private EditText et_password;
    private Button btn_login;
    private Button btn_logout;

    private IGuideAidlInterface iGuideAidlInterface;
    boolean isConnect;
    
    private ServiceConnection serviceConnection = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName componentName,IBinder iBinder){
            //找到已注册的服务
            iGuideAidlInterface = IGuideAidlInterface,Stub.asInterface(iBinder);
            tv_style.setText("当前状态:连接成功“);
                             isConnect = true;
            try{
                iGuideAidlInterface.registerListener(iGuideListener);
            }catch(Exception e){
                e.printStackTrace();
            }
   }
        @Override
        public void onServiceDisconnected(ComponentName componentName){
            tv_style.setText("当前状态:连接断开");
            isConnect = false;
        }
 };
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_style = findViewById(R.id.tv_style);
        et_accotun = findViewById(R.id.et_accotun);
        et_password = findViewById(R.id.et_password);
        btn_login = findViewById(R.id.btn_login);
        btn_logout = findViewById(R.id.btn_logout);

        Intent intent = new Intent();
        intent.setAction("com.ecarx.membercenter.action.GUIDE");
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);

        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(isConnect){
                    try {
                        Log.e("TAG","btn_login");
                        iGuideAidlInterface.login(String.valueOf(et_accotun.getText()),String.valueOf(et_password.getText()) , getPackageName());
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        btn_logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(isConnect){
                    try {
                        iGuideAidlInterface.logout(getPackageName());
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        try {
            iGuideAidlInterface.unregisterListener(iGuideListener);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        unbindService(serviceConnection);
    }

    private IGuideListener iGuideListener = new IGuideListener.Stub() {
        @Override
        public void onLoginSuccess(final String msg) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_style.setText("当前状态:\n连接成功\n"+msg);

                }
            });
            Toast.makeText(MainActivity.this,"客户端登录成功回调====" + msg,Toast.LENGTH_LONG).show();
        }

        @Override
        public void onLoginFail(final String msg) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_style.setText("当前状态:\n连接成功\n"+msg);
                    Toast.makeText(MainActivity.this,"客户端登录失败回调====" + msg,Toast.LENGTH_LONG).show();
                }
            });
        }

        @Override
        public void onLogoutSuccess(final String msg) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_style.setText("当前状态:\n连接成功\n"+msg);
                    Toast.makeText(MainActivity.this,"客户端登出成功回调====" + msg,Toast.LENGTH_LONG).show();
                }
            });
        }

        @Override
        public void onLogoutFail(final String msg) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tv_style.setText("当前状态:\n连接成功\n"+msg);
                    Toast.makeText(MainActivity.this,"客户端登出失败回调====" + msg,Toast.LENGTH_LONG).show();
                }
            });
        }
    };
} 

来自:https://www.yuque.com/yutao-pdqwk/pt44ra/mgfkp0

相关文章

网友评论

      本文标题:基于handler+Binder的Messenger

      本文链接:https://www.haomeiwen.com/subject/qpsnxdtx.html