// После завершения метода база либо открыта, либо нет. Результат вернет метод.

boolean baseIsOpen = hyperHive().openBase(path, key);

В фреймворке методы для длительных операций возвращают объект Call<T>. Сам вызов этого метода не выполняет никакого вызова к API. Создается только подготовка к вызову. Затем объекту Call можно задать необходимые параметры и выполнить запрос. Запрос может быть выполнен как синхронно (в том же потоке), так и асинхронно (в новом потоке).

Пример простого синхронного вызова с возвращением результата в объект класса BaseStatus:

Expand source 

BaseStatus statusAuth = hyperHive()

  // Создаем объект класса Call

  .auth("login", "pass")

  // Запускаем на выполнение в потоке вызова

  .execute();

// Смотрим, что все "ОК"

boolean authOk = statusAuth. isOk;

Пример асинхронного вызова с возвращением результата выполнения в UI потоке:

Expand source 

hyperHive()

  // Создаем объект класса Call

  .auth("login", "pass")

  // настраиваем UI хэндлер для обработки результата запроса

  .setHandler(uiHandler())

  // запускаем выполнение в новом потоке и указываем Callback

  .enqueue(new Callback<BaseStatus>() {

  @Override

  public void onResponse(Call<BaseStatus> call, BaseStatus status) {

  if (status. isOk) {

  // Обрабатываем успех 

  } else {

  // Обрабатываем ошибку

  }

  }

  @Override

  public void onFailure(Call<BaseStatus> call, Throwable throwable) {

НЕ нашли? Не то? Что вы ищете?

  // Обрабатываем ошибку

  }

});

Для некоторых методов фреймворк позволяет автоматически конвертировать результат выполняемого метода в объект ожидаемого класса путем парсинга JSON-строки. Класс передается в параметре вызываемого метода.

Ожидаемый класс может наследоваться от класса StatusDataGeneric<T>, в котором T - ожидаемый класс в поле "data".

Пример создания ожидаемого класса:

Expand source 

// List<Datum> - ожидаемый класс в поле "data".

public static class TableMaterialStatus extends StatusDataGeneric<List<Datum>> {

}

Пример вызова запроса с указанием ожидаемого класса:

Expand source 

// Синхронный

TableMaterialStatus res = hyperHive().query(sqliteDir, query, TableMaterialStatus. class).execute();

//Асинхронный

hyperHive().query(sqliteDir, query, TableMaterialStatus. class)

  .enqueue(new Callback<TableMaterialStatus>() {

  @Override

  public void onResponse(Call<TableMaterialStatus> call, TableMaterialStatus tableMaterialStatus) {

  //Можно делать что-то с результатом

  List<Datum> data = tableMaterialStatus. data; 

  }

  @Override

  public void onFailure(Call<TableMaterialStatus> call, Throwable t) {

  //не получилось получить результат для ожидаемого класса

  }

});

Безопасный вызов асинхронных методов

При выполнении асинхронных запросов из Activity, возникают многочисленные проблемы, связанные с жизненным циклом Activity.

Приведенное ниже описание использования фреймворка позволяет упростить разработку и получить ряд следующих преимуществ:

исключаются утечки памяти, связанные с вызовом асинхронных методов; если в процессе выполнения асинхронного метода Activity будет пересоздана, результат будет обработан в новой Activity и не потеряется; не нужно сохранять ссылки на вызовы для их отмены; устраняется проблема поддержки поворотов.

Для начала работы рекомендуется создать (как наиболее простой способ) абстрактный базовый класс Activity или Fragment. В дальнейшем его можно использовать при создании новых классов Activity или Fragment.

Пример реализации базового класса Activity:

Expand source 

public abstract class HyperHiveActivity extends AppCompatActivity implements HyperHiveView {

  // Помогает в реализации интерфейса HyperHiveView

  private HyperHiveViewHelper hyperHiveViewHelper;

  @Override

  protected void onCreate(@Nullable Bundle savedInstanceState) {

  super. onCreate(savedInstanceState);

  // Восстановление данных с помощью

  // библиотеки Icepick (использование не обязательно)

  Icepick. restoreInstanceState(this, savedInstanceState);

  hyperHiveViewHelper = new HyperHiveViewHelper(this);

  hyperHiveViewHelper. onCreate(savedInstanceState);

  }

  @Override

  protected void onSaveInstanceState(Bundle outState) {

  super. onSaveInstanceState(outState);

  // Сохранение данных с помощью библиотеки

  // Icepick (использование не обязательно)

  Icepick. saveInstanceState(this, outState);

  hyperHiveViewHelper. onSaveInstanceState(outState);

  }

  @Override

  protected void onPause() {

  super. onPause();

  hyperHiveViewHelper. onPause();

  }

  @Override

  protected void onResume() {

  super. onResume();

  hyperHiveViewHelper. onResume();

  }

  @Override

  protected void onDestroy() {

  super. onDestroy();

  if (isFinishing()) {

  // нужно вызывать, когда Activity окончательно уничтожается

  hyperHiveViewHelper. onFinishing();

  }

  }

  //idScope будет нужен для создания запросов

  @Override

  public String getIdScope() {

  return hyperHiveViewHelper. getIdScope();

  }

  //выполняется ли запрос с соответствующим CallbackID

  @Override

  public boolean isHaveActiveTask(CallbackID callbackID) {

  return hyperHiveViewHelper. isHaveActiveTask(callbackID);

  }

  //выполняются ли запросы в данной области

  @Override

  public boolean isHaveActiveTasks() {

  return hyperHiveViewHelper. isHaveActiveTasks();

  }

  //выполняется отмена всех активных задач

  @Override

  public boolean cancelAllTask() {

  return hyperHiveViewHelper. cancelAllTask();

  }

  //выполняется отмена активной задачи с соответствующим CallbackID;

  @Override

  public boolean cancelTask(CallbackID callbackID) {

  return hyperHiveViewHelper. cancelTask(callbackID);

  }

}

Все методы интерфейса, кроме трех: (getIDs(), getCallback(CallbackID callbackID), getProgressCallListener(CallbackID callbackID)) – необходимо реализовать в базовом классе. Для реализации методов нужно использовать HyperHiveViewHelper с вызовом соответствующих методов. Далее базовую Activity можно использовать для создания новых Activity.

Ниже приведен абстрактный пример Activity с двумя типами запросов, с поддержкой сохранения/восстановления данных при пересоздании Activity:

Expand source 

public class QueryExampleActivity extends HyperHiveActivity {

  private String TAG = this. getClass().getSimpleName();

  // Создаем перечисление с типами различных вызовов

  enum QueryType implements CallbackID {

  AUTH, GET

  }

  // аннотация @State используется библиотекой Icepick

  // для определения полей, которые нужно сохранять и восстанавливать

  @State

  boolean isAuthorized;

  @State

  ResultForGet resultForGet;

  @Override

  protected void onCreate(@Nullable Bundle savedInstanceState) {

  super. onCreate(savedInstanceState);

  Button buttonLogin = (Button) findViewById(R. id. btn_login);

  buttonLogin. setOnClickListener(new View. OnClickListener() {

  @Override

  public void onClick(View v) {

  hyperHive()

  .auth("login", "pass")

  .setHandler(uiHandler())

  .enqueue(getIdScope(), AUTH);

  }

  });

  Button buttonGet = (Button) findViewById(R. id. btn_get);

  buttonGet. setOnClickListener(new View. OnClickListener() {

  @Override

  public void onClick(View v) {

  hyperHive()

  .get("resourceName", ResultForGet. class)

  .setHandler(uiHandler())

  .enqueue(getIdScope(), GET);

  }

  });

  }

  @Override

  protected void onPostCreate(@Nullable Bundle savedInstanceState) {

  super. onPostCreate(savedInstanceState);

  updateViewsState(isAuthorized);

  updateViewsState(resultForGet);

  }

  public void updateViewsState(boolean isAuthorized) {

  if (isAuthorized) {

  // какой-то код 

  }

  }

  public void updateViewsState(ResultForGet resultForGet) { 

  // обновляем отображение в соответствии с полученным resultForGet 

  }

  @Override

  public CallbackID[] getIDs() {

  return QueryType. values();

  }

  @Override

  public Callback getCallback(CallbackID callbackID) {

  final QueryType queryType = QueryType. valueOf(callbackID. toString());

  switch (queryType) {

  case AUTH:

  return new Callback<BaseStatus>() {

  @Override

  public void onResponse(Call call, BaseStatus baseStatus) {

  isAuthorized = baseStatus. isOk;

  Log. d(TAG, "AUTH isOk = " + isAuthorized);

  updateViewsState(isAuthorized);

  }

  @Override

  public void onFailure(Call call, Throwable t) {

  Log. e(TAG, "Error " + queryType +": ", t);

  }

  };

  case GET:

  return new Callback<ResultForGet>() {

  @Override

  public void onResponse(Call call, ResultForGet result) {

  Log. d(TAG, "GET isOk = " + result. isOk);

  if (result. isOk) {

  resultForGet = result;

  updateViewsState(resultForGet);

  }

  }

  @Override

  public void onFailure(Call call, Throwable t) {

  Log. e(TAG, "Error " + queryType +": ", t);

  }

  };

  }

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17