在我团队的Android应用程序中,我有一个从启动运行的服务,它与服务器通信以执行诸如登录,注册,在电话之间聊天和更新电话数据库等操作。
我需要让我的服务与双向活动进行通信:例如,我正在处理登录活动,用户名和密码是从应用程序屏幕上的文本字段中获取的字符串,我已经能够将它们传递给服务,以便它向服务器发送授权命令。
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
messenger.send(msg);
}
catch (RemoteException e) {
}
这可以像我预期的那样工作。当服务器响应一条消息,说明登录是否成功时,我需要它将消息传递回活动,以便我可以成功启动主活动,或者如果没有则提示重新进入。
我尝试使用msg.replyTo字段来获取返回信使以发回信息,但是当我运行应用程序时,它会以空指针异常关闭,我不知道为什么会发生这种情况。以下是似乎是罪魁祸首的代码:
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m;
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
m = Message.obtain(null, LoginActivity.OK);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
m = Message.obtain(null, LoginActivity.ERR);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
break;
空指针似乎来自
msg.replyTo.send(m);
两种情况下的代码行(登录成功和登录失败)
任何帮助解决这个问题都将非常感激:)
答案 0 :(得分:1)
正如格雷格在评论中指出的那样。您需要在发送原始邮件的位置设置if
int。
可在此处找到一个示例:http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
答案 1 :(得分:0)
我认为您忘记了通过Service捆绑发送对Login Activity的响应。 因此,我在Messenger Service中进行了一些更改
定义一个全局变量并在传入处理程序中进行一些更改
static final int LOGIN_STATUS = 1;
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m = Message.obtain(null, LOGIN_STATUS);
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
b.putString("responseC",c);
b.putString("responseStatus",status);
b.putString("responseMessage",message)
m.setData(b);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
/*if something is wrong with username and password you can put
a toast*/
}
break;
现在,我们必须在LoginActivity和 在登录活动中也使用IncomingHandler
class IncomingHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case ChatService.LOGIN_STATUS:
String C = msg.getData().getString("responseC");
String Status = msg.getData().getString("responseStatus");
String Message = msg.getData().getString("responseMessage");
//Here is your response in LoginActivity, enjoy!!!
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN_SATUS,0,0);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
msg.replyTo = mMessenger;
messenger.send(msg);
}
catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
此代码运行良好,希望对您有所帮助, 谢谢