Android Сервис-Активность 2 способа связи - PullRequest
4 голосов
/ 29 февраля 2012

в приложении 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);

строка кода в обоих случаях (успешный вход и неудачный вход)

Любая помощь для решения этой проблемы будет принята с благодарностью:)

Ответы [ 2 ]

1 голос
/ 12 августа 2015

Как указывает Грегг в комментариях. Вам нужно установить msg.replyTo = messenger; в том месте, куда вы отправляете исходное сообщение.

Пример можно найти здесь: http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html

0 голосов
/ 17 сентября 2018

Я думаю, что вы забыли отправить ответ на активность входа в пакет из службы.Итак, я сделал некоторые изменения в Messenger Service

, определил одну глобальную переменную и внес некоторые изменения в 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;

Теперь мы должны отловить этот ответ в нашемLoginActivity и принять IncomingHandler в Login Activity также

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.

}

Этот код работает отлично, надеюсь, он поможет вам, Спасибо

...