// После завершения метода база либо открыта, либо нет. Результат вернет метод.
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 |


