我目前正在通过我的应用使用的插件与外部服务进行通信。
绑定服务最终会启动一个活动,然后通知主应用程序活动已完成。
问题是,本地广播通知服务。我已将Messenger msg.replyTo
存储到变量中,因此我可以在Handler完成后访问它,但服务仍然受限制。
它确实有效,但我想完全确定没有NullPointer可能,所以我不太喜欢这种方法。
是否有更好的方式与Binder通信,而不是将Messenger存储在变量中?
以下是一些可以更好理解的代码:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
if (intent.getAction().equals("activity_closed") && mReplyMessenger != null) {
mReplyMessenger.send(Message.obtain(null, MSG_RESULT_ACTIVITY_FINISHED));
}
} catch (RemoteException e) {
e.printStackTrace();
}
};
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
mReplyMessenger = null;
try {
switch (msg.what) {
case MSG_START_ACTIVITY: {
mReplyMessenger = msg.replyTo;
[...]
BridgeBinder.this.startActivity(i);
break;
}
[...]
default:
super.handleMessage(msg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
@Override
public IBinder onBind(Intent arg0) {
return mMessenger.getBinder();
}
答案 0 :(得分:0)
我以同样的方式实现双向Messenger。我真的没有看到你的Handler在你的Activity中得到陈旧的引用(因此也就是NPE),但如果你想要格外谨慎,你可以尝试每次在onResume()方法中更新引用,甚至每次都是你收到一条消息。
答案 1 :(得分:0)
如果需要我的课程:
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import com.ubikinformatica.it.lib.commons.modules.log.EMaxLogger;
import java.util.ArrayList;
import java.util.List;
public class MessageManager {
public interface IOnHandleMessage{
// Message Whats
int MSG_HANDSHAKE = 0x1;
void onHandleMessage(Message msg);
}
private static final String TAG = MessageManager.class.getSimpleName();
private Messenger mMsgSender;
private Messenger mMsgReceiver;
private List<Message> mMessages;
public MessageManager(IOnHandleMessage callback, IBinder target){
mMsgReceiver = new Messenger(new MessageHandler(this, callback, MessageHandler.TYPE_ACTIVITY));
mMsgSender = new Messenger(target);
mMessages = new ArrayList<>();
}
public MessageManager(IOnHandleMessage callback){
mMsgReceiver = new Messenger(new MessageHandler(this, callback, MessageHandler.TYPE_SERVICE));
mMsgSender = null;
mMessages = new ArrayList<>();
}
/** Getter & Setter Methods **/
public Messenger getMsgSender() {
return mMsgSender;
}
public void setMsgSender(Messenger sender) {
this.mMsgSender = sender;
}
public Messenger getMsgReceiver() {
return mMsgReceiver;
}
public void setMsgReceiver(Messenger receiver) {
this.mMsgReceiver = receiver;
}
public List<Message> getLastMessages() {
return mMessages;
}
public void addMessage(Message message) {
this.mMessages.add(message);
}
/** Public Methods **/
public void sendMessage(int what, int arg1, int arg2, Bundle msgData){
if(mMsgSender != null && mMsgReceiver != null) {
try {
Message msg = Message.obtain(null, what, arg1, arg2);
msg.replyTo = mMsgReceiver;
if(msgData != null){
msg.setData(msgData);
}
mMsgSender.send(msg);
} catch (RemoteException rE) {
EMaxLogger.onException(TAG, rE);
}
}
}
public void sendHandshake(){
if(mMsgSender != null && mMsgReceiver != null){
sendMessage(IOnHandleMessage.MSG_HANDSHAKE, 0, 0, null);
}
}
}
import android.os.Handler;
import android.os.Message;
public class MessageHandler extends Handler {
// Types
final static int TYPE_SERVICE = 0x1;
final static int TYPE_ACTIVITY = 0x2;
private MessageManager mMessageManager;
private MessageManager.IOnHandleMessage mCallback;
private int mType;
public MessageHandler(MessageManager msgManager, MessageManager.IOnHandleMessage callback, int type){
this.mMessageManager = msgManager;
this.mCallback = callback;
this.mType = type;
}
/** Override Handler Methods **/
@Override
public void handleMessage(Message msg){
this.mMessageManager.addMessage(msg);
switch(msg.what){
case MessageManager.IOnHandleMessage.MSG_HANDSHAKE:
switch(mType){
case TYPE_SERVICE:
this.mMessageManager.setMsgSender(msg.replyTo);
this.mMessageManager.sendHandshake();
break;
case TYPE_ACTIVITY:
break;
}
break;
default:
if(mCallback != null){
mCallback.onHandleMessage(msg);
}
break;
}
}
}
实际上,新的JobService和JobIntentService存在一些问题,因为它们不能返回除JobScheduler IBinder引擎之外的另一个IBinder,但是我现在想解决它们:D
希望这很有帮助,编码不错:D 再见
确定问题解决了,您可以将Messenger放在一个包裹中,然后通过意图将其发送到服务中。 因此,通过这种方式,在JobIntentService中,“ onBind”方法将返回JobScheduler IBinder引擎,并且您可以在意图内获得Messenger的活页夹!
因此,您仅通过回调在活动中初始化MessageManager,然后通过“ enqueueWork”启动服务,并有意将MessengerReceiver放入该服务。在JobIntentService内部,可以通过在Messenger的“ onBind”和“ onHandleWork”方法中使用Messenger的“ getBinder()”方法来获取IBinder,从而初始化MessageManager。 当您拥有活动的MessengerReceiver的IBinder时,可以使用构造函数“回调+活页夹”来初始化MessageManager。 然后在“服务”中发送“握手”,在活动中他将设置“发件人”。
您必须更改MessageHandler的“ handleMessage”替代方法: 现在的方法是这样:
@Override
public void handleMessage(Message msg){
this.mMessageManager.addMessage(msg);
switch(msg.what){
case MessageManager.IOnHandleMessage.MSG_HANDSHAKE:
switch(mType){
case TYPE_SERVICE:
this.mMessageManager.setMsgSender(msg.replyTo);
this.mMessageManager.sendHandshake();
break;
case TYPE_ACTIVITY:
break;
}
break;
default:
if(mCallback != null){
mCallback.onHandleMessage(msg);
}
break;
}
}
您需要删除类型,因为您不再需要它。 因此,在获取和握手时,在类“ MessageHandler”内的“ handleMessage”方法的切换中,您必须执行以下操作:
[...]
case MessageManager.IOnHandleMessage.MSG_HANDSHAKE:
if(this.mMessageManager.getMsgSender() == null){
this.mMessageManager.setMsgSender(msg.replyTo);
this.mMessageManager.sendHandshake();
}
[...]
这样可以解决JobIntentService的问题;) 希望这对您有所帮助! 编码不错<3