简体   繁体   English

Android Service-Activity 2方式沟通

[英]Android Service-Activity 2 way communication

in my team's Android application I have a service running from boot which communicates with a server to perform operations such as logging in, registering, chatting between phones and updating the phone database. 在我的团队的Android应用程序中,我有一个从启动运行的服务,它与服务器通信以执行诸如登录,注册,在电话之间聊天和更新电话数据库等操作。

I need to make my service communicate with the activity bi-directionally: for example I am working on the login activity at the moment and the username and passwords are Strings taken from a text field on the app screen and I have been able to pass them to the service for it to send an authorisation command to the server. 我需要让我的服务与双向活动进行通信:例如,我正在处理登录活动,用户名和密码是从应用程序屏幕上的文本字段中获取的字符串,我已经能够通过它们向服务器发送授权命令到服务器。

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) {

    }

This works as I would have expected. 这可以像我预期的那样工作。 When the server responds with a message saying whether or not the login was sucessful, I need it to pass a message back to the activity so that I can start the main activity if succesful or prompt for re-entry if not. 当服务器响应一条消息,说明登录是否成功时,我需要它将消息传递回活动,以便我可以启动主要活动,如果成功或提示重新进入,如果没有。

I tried to use the msg.replyTo field to get the return messenger to send the information back, but when I run the app it force closes with a null pointer exception and I have no idea why this is happening. 我尝试使用msg.replyTo字段来获取返回信使以发回信息,但是当我运行应用程序时,它会以空指针异常关闭,我不知道为什么会发生这种情况。 Here is the code that seems to be the culprit: 这是代码似乎是罪魁祸首:

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;

The null pointer seems to be coming from the 空指针似乎来自于

msg.replyTo.send(m);

line of code in both cases (login succesful and login failed) 两种情况下的代码行(登录成功和登录失败)

Any help to fix this problem would be greatly appreciated :) 任何帮助解决这个问题将不胜感激:)

As Gregg points out in the comments. 正如格雷格在评论中指出的那样。 You need to set msg.replyTo = messenger; 你需要设置msg.replyTo = messenger; int he place where you send the original message. int他发送原始邮件的地方。

An example can be found here: http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html 可以在此处找到一个示例: http//www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html

I think you forgot to send response to Login Activity by bundle from Service. 我想你忘了通过服务包发送对Login Activity的响应。 So, i made some changes in Messenger Service 所以,我在Messenger Service中做了一些更改

define one global variable and made some changes in Incoming Handler 定义一个全局变量并在Incoming Handler中进行一些更改

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;

Now we have to catch this response in our LoginActivity and take IncomingHandler in Login Activity also 现在我们必须在LoginActivity中捕获此响应,并在Login Activity中使用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.

}

This code is working perfectly, hope it will help you, Thanks 这段代码工作正常,希望它会对你有所帮助,谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM