我正在尝试在我的服务和活动设置之间进行双向通信。为此,我像平常一样启动我的服务,发送一条消息,将replyTo设置为我的Activity中的Messenger,然后将其发送到我的服务。这样我就可以在两个方向上发送消息。以下是我的Activty中的一些相关代码:
private Messenger mService = null;
private final Messenger mMessenger = new Messenger(new IncomingHandler());
private ServiceConnection mConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder service)
{
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className)
{
mService = null;
mBound = false;
}
};
private void initMessenger()
{
Message messageHandler = Message.obtain(null, NetworkService.MSG_GET_HANDLER, 0, 0);
messageHandler.replyTo = mMessenger; //Set the replyTo to give a reference
try
{
mService.send(messageHandler);
}
catch(RemoteException e)
{
e.printStackTrade();
}
catch(NullPointerException e)
{
e.printStackTrace(); //Why!!!
}
}
public void onCreate()
{
...
//Create the intent to start the network service
Intent iService = new Intent(this, NetworkService.class);
int[] connectionConfig = {CONNECTION_BT};
iService.putExtra(CONNECTION_CONFIG, connectionConfig);
bindService(iService, mConnection, Context.BIND_ABOVE_CLIENT);
startService(iService);
initMessenger();
}
当我尝试调用mService.send()时抛出NullPointerException,这很可能是因为当时mService为null。如果我在一个Button的OnClickListener中移动initMessenger()代码就可以正常工作,这就是混乱的原因。我应该在启动服务后等待一段时间才能使用它吗?
答案 0 :(得分:3)
为什么不在initMessenger()
方法中拨打onServiceConnected()
?那样mService
肯定会被分配。
答案 1 :(得分:2)
mService
null
表示此时您的服务尚未(尚未)调用onServiceConnected()
。
不幸的是,documentation并未表示bindService()
返回与ServiceConnection
中的方法之间存在差距。
事实上,bindService()
应该在服务启动时返回true
,这意味着一旦代码通过此阶段,服务就应该启动。因此,我会在调用true
之前检查bindService()是否已返回initMessenger()
,因为服务可能无法正常启动。
onServiceConnected()
中的代码也可能抛出异常(因为它可能在工作线程上被调用,不会导致您的应用程序崩溃),您可能需要重新检入你的日志检查是否是这种情况。
此外,startService(iService);
在此上下文中是多余的,bindService()
启动服务,在服务上调用startService
只需向其发送消息。
答案 2 :(得分:1)
是。只有在您知道自己受其约束后才能使用该服务。
因为您尝试绑定到服务后尝试立即使用您的服务,所以您无法保证将连接到该服务。有时服务可能会立即绑定,因此您不会崩溃。有时会花费更长时间,因此您对initMessenger()
的调用将导致您的NPE,因为该服务尚未连接。
将initMessenger()
电话移动到您的按钮点击是允许您的服务时间绑定。此外,您应该检查以确保您受到约束(即使您给它时间),因为绑定可能会失败