AIDL解析(二 )让Service主动调起Activity吧!

在上一篇文章《AIDL解析(一)两个应用之间使用AIDL进行通信的例子》中,我们学会了Activity如何向Service传递数据,但是Service却不能主动向Activity传递数据,比如说我们想让Service开启一个线程,每隔五秒传递一个消息给Activity,应该怎么做呢?这就要用到回调机制了。

效果图:


如图所示,我们要的效果是Client客户端会主动接收到Service的消息


搭建Client项目

1  首先,我们新建一个IService.aidl的文件,代码如下:

package com.viii.aidlclient;

import com.viii.aidlclient.MessageCenter;

interface IService {
  void registerCallback(MessageCenter cb);
  void unregisterCallback(MessageCenter cb);
}

2  新建一个CallBackActivity,布局和代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="150dp"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="200dp"
        android:text="发送"/>

    <TextView
        android:id="@+id/tv_modify"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="服务端发来的内容:"
        android:layout_below="@+id/editText"
        />


</RelativeLayout>

通过 mService.registerCallback(mCallback)去绑定回调

package com.viii.aidlclient;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;


import java.util.List;

public class CallBackActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText editText;
    private TextView tv_modify;

    //标志当前与服务端连接状况的布尔值,false为未连接,true为连接中
    private boolean mBound = false;

    private IService mService;

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String str = (String) msg.obj;
            tv_modify.setText(str);
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_back);
        editText = (EditText) findViewById(R.id.editText);
        tv_modify = (TextView) findViewById(R.id.tv_modify);
        findViewById(R.id.button).setOnClickListener(this);
    }

    /**
     * 跨进程绑定服务
     */
    private void attemptToBindService() {
        Intent intent = new Intent();
        intent.setAction("com.vvvv.callbackaidl");
        intent.setPackage("com.iiiv.aidlserver");
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!mBound) {
            attemptToBindService();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mServiceConnection);
            mBound = false;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mService != null) {
            try {
                mService.unregisterCallback(mCallback);
            } catch (RemoteException e) {
                Log.e(getClass().getSimpleName(), "", e);
            }
        }

    }

    /**
     * service的回调方法
     */
    private MessageCenter.Stub mCallback = new MessageCenter.Stub() {

        @Override
        public List<Info> getInfo() throws RemoteException {
            return null;
        }

        @Override
        public Info addInfo(Info info) throws RemoteException {
            Message message = new Message();
            message.obj = info.getContent();
            handler.sendMessage(message);
            return null;
        }
    };

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(getLocalClassName(), "完成绑定aidlserver的AIDLService服务");
            mService = IService.Stub.asInterface(service);
            try {
                mService.registerCallback(mCallback);
            } catch (RemoteException e) {
                Log.e(getClass().getSimpleName(), "", e);
            }

            mBound = true;

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(getLocalClassName(), "无法绑定aidlserver的AIDLService服务");
            mBound = false;
        }
    };

    @Override
    public void onClick(View view) {
        String content;
        switch (view.getId()) {
            case R.id.button:
                content = editText.getText().toString();
                break;
        }
    }
}


搭建Service项目

1、拷贝IService.aidl文件到aidi目录下,新建一个CallbackAIDLService的文件
 mCallbacks.register(cb)绑定回调之后,通过mCallbacks.beginBroadcast(), mCallbacks.getBroadcastItem(i).addInfo(info),mCallbacks.finishBroadcast()3个步骤来进行发送
package com.iiiv.aidlserver.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.viii.aidlclient.IService;
import com.viii.aidlclient.Info;
import com.viii.aidlclient.MessageCenter;

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


/**
 * 服务端的AIDLService.java
 */
public class CallbackAIDLService extends Service {

    public final String TAG = this.getClass().getSimpleName();



    private boolean quit = false;
    private int count;

    private Handler timeHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.i(getClass().getSimpleName(), "发送消息:" + msg.what);
            Info info = new Info();
            info.setContent("来自服务器的消息:"+msg.what);
            callBack(info);
            super.handleMessage(msg);
        }
    };


    private RemoteCallbackList<MessageCenter> mCallbacks = new RemoteCallbackList<MessageCenter>();
    private IService.Stub mBinder = new IService.Stub() {

        @Override
        public void unregisterCallback(MessageCenter cb){
            if(cb != null) {
                mCallbacks.unregister(cb);
            }
        }

        @Override
        public void registerCallback(MessageCenter cb){
            if(cb != null) {
                mCallbacks.register(cb);
            }
        }
    };

    private void callBack(Info info) {
        int N = mCallbacks.beginBroadcast();
        try {
            for (int i = 0; i < N; i++) {
                mCallbacks.getBroadcastItem(i).addInfo(info);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        }
        mCallbacks.finishBroadcast();
    }

    /**
     * 初始化一个定时器
     */
    private void initTimer() {
        new Thread() {
            @Override
            public void run() {
                while (!quit) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Message message = new Message();
                    message.what = count++;
                    timeHandler.sendMessage(message);
                }
            }
        }.start();
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(getClass().getSimpleName(), String.format("on bind,intent = %s", intent.toString()));
        initTimer();
        return mBinder;
    }

    @Override
    public void onDestroy() {
        quit = true;
        mCallbacks.kill();
        super.onDestroy();

    }


}
2  在AndroidManifest中注册
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.iiiv.aidlserver">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service
            android:name=".service.AIDLService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.vvvv.aidl"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>

        <service
            android:name=".service.CallbackAIDLService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.vvvv.callbackaidl"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>
    </application>

</manifest>

现在,我们可以随时向Client发送消息了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值