个人博客系统

相对于AIDL,以Messenger来完成不同进程之间的通信要更加简单,这种实现方式是基于AIDL的,但是我们无需再编写AIDL文件,并且该方式是线程安全的,所有发送出去的消息都会被存储在一个消息队列中被依次处理。

这里创建两个测试应用,分别为ServiceApp和ClientApp,在ClientApp中,点击按钮,给ServieApp发送消息,ServiceApp打印出消息,同时,给ClientApp答复一条消息,具体操作步骤。

1、首先在ServiceApp中新建一个Service,在Service中创建一个Handler,用来处理从客户端发来的消息,onBind方法中,返回持有Handler对象的Messager,代码如下:

public class MessengerService extends Service {
    private static final int MSG_SAY_HELLO = 0x001;
    private static final int MSG_SAY_HI = 0x002;
    
    final Messenger mServiceMsger = new Messenger(new ServiceHandler());

    public MessengerService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mServiceMsger.getBinder();
    }

    class ServiceHandler extends Handler{
        @Override
        public void handleMessage(Message msgFromClient) {
            switch (msgFromClient.what){
                case MSG_SAY_HELLO:
                    Log.e("ZWH", "hello from client!");
                    try {
                        //休眠2秒钟
                        Thread.sleep(2000);
                        Message msg2Client = Message.obtain();
                        msg2Client.what = MSG_SAY_HI;
                        //msgFromClient.replyTo得到Client端Messager对象,并回复一条消息
                        msgFromClient.replyTo.send(msg2Client);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    break;
            }
            super.handleMessage(msgFromClient);
        }

    }
}

2、同时,不要忘记注册service,因为是不同进程通信,所以需要给service添加action值。

<service
    android:name=".MessengerService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="cn.zhaoweihua.aidl.messagerservice"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</service>

3、在ClientApp中,创建一个Activity,该Activity通过bindService的方式与ServiceApp中的服务绑定,绑定成功可以获取到service端的Messenger对象,通过该对象即可以给service发送消息,同时,创建一个新的Messenger对象,赋给replyTo一起发送到service端,以便service端通过该Messenger来回传消息。

public class MainActivity extends AppCompatActivity {

    private static final int MSG_SAY_HELLO = 0x001;
    private static final int MSG_SAY_HI = 0x002;
    private static final String SERVICE_ACTION = "cn.zhaoweihua.aidl.messagerservice";

    private Messenger serviceMsger;
    private boolean isConnected;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定ServiceApp中的Service
        bindServiceInvoked();

    }
    private void bindServiceInvoked() {
        Intent msgerService = new Intent(SERVICE_ACTION);
        //在Android5.0版本之前,可以通过bindService来直接绑定隐式意图
        // 但是5.0版本之后,Android只允许以显示意图的方式bindService,
        //createExplicitFromImplicitIntent方法的作用就是将隐式意图转换为显示意图
        msgerService = new Intent(createExplicitFromImplicitIntent(this,msgerService));
        bindService(msgerService, mServiceConnection, Context.BIND_AUTO_CREATE);
    }
    //点击按钮,如果已经和ServiceApp中的service绑定成功,则发送一条信息
    public void btnClick(View view){
        try {
            Message msgFromClient = Message.obtain();
            msgFromClient.what = MSG_SAY_HELLO;
            if(isConnected){
                //将client端的Messager赋值给message的replyTo,以便Service端回传信息
                msgFromClient.replyTo = clientMsger;
                serviceMsger.send(msgFromClient);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    //处理service端发送过来的信息
    private Messenger clientMsger = new Messenger(new Handler(){
        @Override
        public void handleMessage(Message msgFromService) {
            switch (msgFromService.what){
                case MSG_SAY_HI:
                    Log.e("ZWH", "HI from Service!");
                    break;
                default:
                    super.handleMessage(msgFromService);
            }
        }
    });
    //用于bindService时回调参数
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定成功后,获取service端的Messager,
            // 通过Messager就可以给service发送消息了
            serviceMsger = new Messenger(service);
            isConnected = true;
            Toast.makeText(MainActivity.this, "connected!!!", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isConnected = false;
            serviceMsger = null;

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }

    //Android5.0中service的intent一定要显性声明,
    // 直接action形式调用会出现IllegalArgumentException: Service Intent must be explicit
    public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }
        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);
        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);
        // Set the component to be explicit
        explicitIntent.setComponent(component);
        return explicitIntent;
    }
}

4、将ServiceApp和ClientApp安装到测试机中,点击ClientApp中的按钮,效果如下:

20161123210354.png


网站公告
这里是挨踢农民工的博客,欢迎光临,以上为一段测试信息。
生命在于折腾
博客分类
文章归档 更多
网站统计
当前在线人数:29
注册会员数:108
网站总浏览量:161873
文章总数:17
留言总数:9
评论总数:21
分类总数:6
友情链接总数:1