美文网首页
基于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