После отслеживания поддержки кэширования в Apollo Android
здесь: Поддержка кэшированных ответов для Android
И уже пытался запросить в автономном режиме, он работает нормально, и данные поступают из кэша
Первый сценарий после открытия приложения - загрузка списка данных с использованием запроса из объекта «MyApolloClinet», который является пользовательским классом, наследуемым от «ApolloClient»
После получения данных с использованием метода ".watcher (). EnqueueAndWatch ()" для ответа обратного вызова из Apollo с новыми данными и обновления recyclerView
Я выбираю элемент для обновления или "Мутирую" запись из списка данных запроса, чтобы изменить ее в кеше и базе данных, конечно.
Я могу щелкнуть любой элемент, а затем отобразить диалоговое окно для редактирования названия этого элемента.
запись
После отправки обновленного имени с использованием Mutation
, как правило, кэш-память изменилась, а база данных также изменилась.
Проблема здесь: интерфейс вообще не изменился, потому что .watcher()
метод, который возвращает экземпляр ApolloQueryWatcher
, у которого есть метод с именем enqueueAndWatch
, не вызывает как слушатель любых изменений для обновления пользовательского интерфейса и списка с новым измененным значением этой записи
Вот некоторые фрагменты из моего кода,
Я использую Kotlin и Java.
Способ получения данных пользователей из базы данных с использованием Query
fun getAllUsers() {
progress.visibility = VISIBLE
MyApolloClient.getApolloClient(this).query(GetUsersWithPagesQuery.builder().build())
.watcher().enqueueAndWatch(object : MyApolloClient.MyCallBack<GetUsersWithPagesQuery.Data>(this) {
override fun onResponseUI(response: Response<GetUsersWithPagesQuery.Data>) {
progress.visibility = GONE
if (response.data() != null) {
reachBottom = false
users.clear()
for (i in response.data()!!.users()) {
val u = GetUsersWithPagesQuery.Data1("", i.id(), i.name(), i.email())
users.add(u)
}
adapter.notifyDataSetChanged()
}
}
override fun onFailureUI(response: ApolloException) {
}
})
}
Пользовательский обратный вызов для использования ответа в пользовательском интерфейсе
public static abstract class MyCallBack<T> extends ApolloCall.Callback<T> {
Activity activity;
public MyCallBack(Activity activity) {
this.activity = activity;
}
@Override
public void onResponse(@NotNull com.apollographql.apollo.api.Response<T> response) {
activity.runOnUiThread(() -> onResponseUI(response));
}
public abstract void onResponseUI(@NotNull com.apollographql.apollo.api.Response<T> response);
public abstract void onFailureUI(@NotNull ApolloException response);
@Override
public void onFailure(@NotNull ApolloException e) {
activity.runOnUiThread(() -> onFailureUI(e));
}
}
получение объекта Apollo Client с поддержкой кэширования
public static ApolloClient getApolloClient(Context context) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addNetworkInterceptor(httpLoggingInterceptor);
builder.addNetworkInterceptor(chain -> {
Request original = chain.request();
Request.Builder builder1 = original.newBuilder().method(original.method(), original.body());
builder1.header("Authorization", "Bearer " + PrefManager.getInstance(context).getAPIToken());
return chain.proceed(builder1.build());
});
OkHttpClient okHttpClient = builder.build();
//Directory where cached responses will be stored
File file = new File(context.getApplicationContext().getFilesDir(), "apolloCache");
//Size in bytes of the cache
long size = 1024 * 1024;
//Create the http response cache store
DiskLruHttpCacheStore cacheStore = new DiskLruHttpCacheStore(file, size);
ApolloSqlHelper apolloSqlHelper = ApolloSqlHelper.create(context, "zari");
//Create NormalizedCacheFactory
NormalizedCacheFactory cacheFactory = new SqlNormalizedCacheFactory(apolloSqlHelper);
//Create the cache key resolver, this example works well when all types have globally unique ids.
CacheKeyResolver resolver = new CacheKeyResolver() {
@NotNull
@Override
public CacheKey fromFieldRecordSet(@NotNull ResponseField field, @NotNull Map<String, Object> recordSet) {
return formatCacheKey((String) recordSet.get("id"));
}
@NotNull
@Override
public CacheKey fromFieldArguments(@NotNull ResponseField field, @NotNull Operation.Variables variables) {
return formatCacheKey((String) field.resolveArgument("id", variables));
}
private CacheKey formatCacheKey(String id) {
if (id == null || id.isEmpty()) {
return CacheKey.NO_KEY;
} else {
return CacheKey.from(id);
}
}
};
apolloClient = ApolloClient.builder()
.serverUrl(url)
//.httpCache(new ApolloHttpCache(cacheStore))
.normalizedCache(cacheFactory, resolver)
.okHttpClient(okHttpClient)
.build();
return apolloClient;
}
диалоговое окно с текстом редактирования для обновления элемента из списка в Recycler Adapter
builder.setPositiveButton("Change", (dialog, which) -> {
if (!n.isEmpty())
MyApolloClient.getApolloClient(activity).mutate(UpdateUserMutation.builder().id(user
.id()).name(n).build()).enqueue(new MyApolloClient.MyCallBack<UpdateUserMutation.Data>(activity) {
@Override
public void onResponseUI(@NotNull Response<UpdateUserMutation.Data> response) {
if (response.errors() != null && response.errors().size() > 0) {
StaticMembers.toastMessageShort(activity, response.errors().get(0).message());
} else {
StaticMembers.toastMessageShort(activity, response.data().updateUser().name() + " updated");
}
}
@Override
public void onFailureUI(@NotNull ApolloException response) {
}
});
});
Итак, кто-нибудь может помочь, пожалуйста?