2016-02-08 2 views
0

Я создаю систему входа для приложения для Android. Я использую OkHttp для подключения к моему серверу и получения ответа JSON.Возвращаемое значение из внутреннего класса по методу

Я определил класс с данными возврата входа (прямо сейчас только истинный/ложный ответ на основе того, существует ли пользователь в базе данных), а затем написал код для подключения к серверу, как показано ниже:

class UserLogin { 
    boolean status; 

    public void setStatus(boolean status) { 
     this.status = status; 
    } 

    public boolean getStatus() { 
     return status; 
    } 
} 

public class ClientServerInterface { 

    OkHttpClient client = new OkHttpClient(); 

    boolean login(Request request) { 
     final Gson gson = new Gson(); 
     client.newCall(request).enqueue(new Callback() { 
      UserLogin login; 
      @Override 
      public void onFailure(Call call, IOException e) { 

      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       login = gson.fromJson(response.body().charStream(), UserLogin.class); 
       login.setStatus(login.status); 
      } 
     }); 
     // need to return the boolean response (status) here 
    } 
} 

код, который передает Request переменную метода login отлично работает. Я хочу, чтобы login возвращал логический ответ, чтобы передать его другим методам в других классах.

Однако, поскольку объект UserLogin определен в callback, я не могу получить к нему доступ в родительском методе. Я сделал метод getStatus, но не знаю, как правильно его использовать, чтобы получить статус в основном методе login.

+1

'// нужно вернуть логический отклик (статус) здесь' => Очевидно, вы не можете этого сделать ... потому что, когда этот метод возвращает запрос, все еще может быть запущен – Selvin

ответ

1

Код, передающий переменную Request в метод входа в систему, работает отлично. Я хочу, чтобы логин возвращал логический ответ, чтобы я мог передать это другим методам в других классах.

вы не можете. enqueue выполняет код Async. Вы не знаете, когда вызывается обратный вызов. Что вы можете сделать, так это добавить параметр «Обратный вызов» в ваш метод входа. Например.

boolean login(Request request, final Callback callback) { 

и либо передать его enqueue,

client.newCall(request).enqueue(callback); 

или вызвать обратный вызов вручную. Например.

@Override 
public void onResponse(Call call, Response response) throws IOException { 
     if (callback != null) { 
      callback.onResponse(call, response); 
     } 
} 

в обеих случаях вызывающий входа получит обратный вызов на указанном объекте и, соответственно, к содержанию он получает, может решить WHA действия предпринять

1

Вы можете сделать это с помощью SynchronousQueue:

final SynchronousQueue<Boolean> queue = new SynchronousQueue<>(); 
client.newCall(request).enqueue(new Callback() { 
     UserLogin login; 
     @Override 
     public void onFailure(Call call, IOException e) { 
      queue.put(false); 
     } 

     @Override 
     public void onResponse(Call call, Response response) throws IOException { 
      queue.put(true); 
     } 
    }); 
return queue.take(); 
+0

ужасная идея, когда вызывается логин (...) на потоке пользовательского интерфейса ... – Selvin

+0

@ Selvin это скорее комментарий к вопросу/требованию OP, чем мой ответ. –

+0

@ AndyTurner благодарит ответ. @ selvin/Andy, я предполагаю, что из ответов я не делаю этого совершенно правильно. Было бы здорово, если бы вы предложили лучшие способы переписать мой код, чтобы это сработало. По сути, мне просто нужно получить переменную 'status' - если метод' login' ничего не возвращает, это нормально. Благодаря! –

0

Добавить переменную loginStatus в класс, как показано ниже, и еще один, чтобы указать завершение операции входа в систему.

public class ClientServerInterface { 

    OkHttpClient client = new OkHttpClient(); 
    private boolean loginStatus = false; 
    private boolean isLoginOperationDone = false; 
    boolean login(Request request) { 
     final Gson gson = new Gson(); 
     client.newCall(request).enqueue(new Callback() { 
      UserLogin login; 
      @Override 
      public void onFailure(Call call, IOException e) { 

      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       login = gson.fromJson(response.body().charStream(), UserLogin.class); 
       loginStatus = login.setStatus(login.status); 
       isLoginOperationDone = true; 
      } 
     }); 
     // need to return the boolean response (status) here 
     while(!isLoginOperationDone) 
     { 
      //not to do anything. 
     } 
     return loginStatus; 
    } 
} 

Обратите внимание, что это может быть немного взломанным, но решит вашу проблему.

+0

нет, это не будет ... ужасная идея, когда login (...) вызывается в потоке пользовательского интерфейса ... – Selvin

0

Путь к работе с AsyncTask. Переопределите метод doInBackground для выполнения HTTP-запросов и получите результат, переопределив метод onPostExecute.

Подробнее здесь: http://developer.android.com/reference/android/os/AsyncTask.html

Еще лучше пойти, чтобы работать в фоновом режиме и для всех API вызовов.

+0

Извините, сэр, но он не использует AsyncTask , Кроме того, я предлагаю пойти с Сервисом, но я считаю, что это немного больше, чем просто простая AsyncTask. –

Смежные вопросы