Android實現組件之間同步的回調通訊

        Android開發中,有時會遇到組件之間相互通訊回調的問題。通常都是經過Android提供的ResultReceiver來實現(ResultReceiver的使用方法很簡單,這裏就很少提了)。android

        但以前在工做中,遇到了一個組件間回調的問題,ResultReceiver沒法知足需求。簡單描述一下問題:service中打開了一個activity,activity須要將一個變量值回調給service,並且這個回調必須是同步的。也就是說activity在確認service接收到了這個變量值後,才能繼續向下執行代碼。衆所周知ResultReceiver的send方法是異步的,send方法執行後,接收方可能尚未收到消息。這樣"不及時"的回調在個人項目中可能會形成狀態不一樣步。git

        那麼,只能本身實現一個同步的回調通訊。github

 

        同步的回調通訊代碼以下:app

        github地址:https://github.com/yuhaiyang89/yhy-utils異步

 

1.定義一個AIDLide

package com.yhy.utils;
interface IChannel {
     void send(int code, in Bundle data);
}

2.定義一個類,實現Parcelable(實現Parcelable是爲了能讓該類在組件中傳遞),並在此類中實現第一步定義的AIDL(經過這個AIDL完成回調)this

package com.yhy.utils.demo;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.yhy.utils.IChannel;

public class SyncResultReceiver implements Parcelable {
    
    public static final Parcelable.Creator<SyncResultReceiver> CREATOR = new Parcelable.Creator<SyncResultReceiver>() {
        
        public SyncResultReceiver createFromParcel(Parcel in) {
            return new SyncResultReceiver(in);
        }

        public SyncResultReceiver[] newArray(int size) {
            return new SyncResultReceiver[size];
        }
    };
    
    // 是本地回調仍是遠程回調
    final boolean mLocal;

    IChannel mBridge;


    public SyncResultReceiver() {
        mLocal = true;
    }

    SyncResultReceiver(Parcel in) {
        mLocal = false;
        mBridge = IChannel.Stub.asInterface(in.readStrongBinder());
    }

    public void send(int code, Bundle data) {
        if (mLocal) {
            onReceiveResult(code, data);
            return;
        }

        if (mBridge != null) {
            try {
                mBridge.send(code, data);
            } catch (Exception e) {
                Log.e("", "",e);
            }
        }
    }

    protected void onReceiveResult(int code, Bundle bundle) {
        // 等待子類去實現此方法,接收消息
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        synchronized (this) {
            if (mBridge == null) {
                mBridge = new MyChannel();
            }
            out.writeStrongBinder(mBridge.asBinder());
        }
    }

    class MyChannel extends IChannel.Stub {
        public void send(int code, Bundle data) {
            onReceiveResult(code, data);
        }
    }
}

實現完畢!spa

 

下面就可使用SyncResultReceiver來實現同步回調了code

例:MainActivity中打開Activity2,Activity2將一些消息同步的回調給MainActivityblog

MainActivity代碼:

package com.yhy.utils.demo;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private int value = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 重寫SyncResultReceiver的onReceiveResult方法接收返回值
        SyncResultReceiver mResultReceiver = new SyncResultReceiver(){
            @Override
            protected void onReceiveResult(int code, Bundle bundle) {

                value = bundle.getInt("value");
                Log.d("TEST", "code=" + code + " | value = " + value);
            }
        };

        // 開啓Activity2
        Intent intent = new Intent(this, Activity2.class);
        intent.putExtra("callback", mResultReceiver);
        startActivity(intent);
    }
}

Activity2代碼:

package com.yhy.utils.demo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class Activity2 extends AppCompatActivity {

    SyncResultReceiver mReceiver = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReceiver = getIntent().getParcelableExtra("callback");

        // 給MainActivity回調值
        Bundle bundle = new Bundle();
        bundle.putInt("value", 1);
        mReceiver.send(1, bundle);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // 給MainActivity回調值
        Bundle bundle = new Bundle();
        bundle.putInt("value", 2);
        mReceiver.send(1, bundle);
    }

    @Override
    protected void onDestroy() {
        // 給MainActivity回調值
        Bundle bundle = new Bundle();
        bundle.putInt("value", 3);
        mReceiver.send(1, bundle);
        super.onDestroy();
    }
}

 

LOG輸出:

03-03 11:50:28.780 2790-2790/? D/TEST: code=1 | value = 103-03 11:50:28.782 2790-2790/? D/TEST: code=1 | value = 203-03 11:53:07.588 2790-2790/? D/TEST: code=1 | value = 3

相關文章
相關標籤/搜索