gpt4 book ai didi

android - 如何使用数据绑定(bind)库将 Firebase 监听器转换为可观察 map ?

转载 作者:行者123 更新时间:2023-11-30 00:46:11 27 4
gpt4 key购买 nike

TL;博士

是否可以隐藏所有Firebase read and write operationsObservableMap后面作为Facade Pattern

所以我们要做的就是:

User oldUser = map.put(user);
User newUser = map.get(primaryKey);

完整问题

根据 Firebase documentation ,为了写入值,我必须通过 DatabaseReference 定义资源路径并设置一个值。

例如,如果我们有一个 User纯文本对象,我们将其设置为:

mDatabase.child("users")
.push()
.setValue(user);

要读取整个users 树,我们必须实现一个ChildEventListener。 .一旦新用户成为树的一部分,就会通过 onChildAdded 接收到它。 :

@Override
public void onChildChanged (DataSnapshot snapshot, String previousChildName) {
Log.i(TAG, snapshot.getValue(User.class));
}

最后,为了读取特定用户,我们使用 ValueEventListener :

mDatabase.child("users")
.child(primaryKey)
.setValue(user)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
Log.i(TAG, snapshot.getValue(User.class));
}

@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, "loadPost:onCancelled", error.getMessage());
}
});

所以可以使用 ObservableMap作为Facade Pattern , 隐藏所有 Firebase read and write operations

最佳答案

TL;博士

我结合了ObservableArrayMapChildEventListener进入 FirebaseArrayMap .

工作FirebaseUI-Android示例可用 here .现在您所要做的就是:

// Remote updates immediately send you your view
map.addOnMapChangedCallback(mUserChangedCallback);

// Non blocking operation to update database
map.create(user);

// Local up-to-date cache
User user = map.get(primaryKey);

记得(取消)注册您的 OnMapChangedCallbackonResumeonPause为了避免ChildEventListener引起的内存泄漏远程更新。

增删改查

首先我们需要为Map 创建一个词库 接口(interface),即:

public interface CRUD<K, V> {

Task<V> create(V value);

Task<V> create(K key, V value);

Task<Void> createAll(SimpleArrayMap<? extends K, ? extends V> array);

Task<Void> createAll(Map<? extends K, ? extends V> map);

V read(K key);

Task<V> delete(K key);

Task<Void> free();

}

该接口(interface)将由FirebaseArrayMap实现,返回将由 Map 返回的相同值 .

这些方法类似于 put , putAllget , 但它们不返回值而是返回 Tasks具有这些值(或异常)。示例:

    @Override
public Task<Void> createAll(Map<? extends K, ? extends V> map) {
Collection<Task<V>> tasks = new ArrayList<>(map.size());
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
tasks.add(create(entry.getKey(), entry.getValue()));
}
return Tasks.whenAll(tasks);
}

@Override
public V read(K key) {
return get(key);
}

@Override
public Task<V> delete(K key) {
final V oldValue = get(key);
final Continuation<Void, V> onDelete = new Continuation<Void, V>() {
@Override
public V then(@NonNull Task<Void> task) throws Exception {
task.getResult();
return oldValue;
}
};
return mDatabaseReference.child(key.toString())
.setValue(null)
.continueWith(onDelete);
}

ObservableArrayMap

我们创建一个摘要 FirebaseArrayMap扩展ObservableArrayMap并实现 ChildEventListenerCRUD .

public abstract class FirebaseArrayMap<K extends Object, V> extends
ObservableArrayMap<K, V> implements ChildEventListener, CRUD<K, V> {

private final DatabaseReference mDatabaseReference;

public abstract Class<V> getType();

public FirebaseArrayMap(@NonNull DatabaseReference databaseReference) {
mDatabaseReference = databaseReference;
}

ChildEventListener将使用 super 方法,将 ObservableArrayMap放入本地缓存。

因此,当写入操作成功完成(或发生远程更改)时,ChildEventListener会自动更新我们的Map

    @Override
public void onCancelled(DatabaseError error) {
Log.e(TAG, error.getMessage(), error.toException());
}

@Override
public void onChildAdded(DataSnapshot snapshot, String previousChildName) {
if (snapshot.exists()) {
super.put((K) snapshot.getKey(), snapshot.getValue(getType()));
}
}

@Override
public void onChildChanged(DataSnapshot snapshot, String previousChildName) {
super.put((K)snapshot.getKey(), snapshot.getValue(getType()));
}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
super.put((K)snapshot.getKey(), snapshot.getValue(getType()));
}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
super.remove(dataSnapshot.getKey());
}

契约(Contract)

CRUD需要接口(interface)才能不中断 Map契约(Contract)。例如,put当在给定位置插入新值时返回先前的值,但此操作现在是异步

对于写操作,这里的技巧是使用 CRUD对于非阻塞Map对于阻塞操作:

    @Override
@WorkerThread
public V put(K key, V value) {
try {
return Tasks.await(create(key, value));
} catch (ExecutionException e) {
return null;
} catch (InterruptedException e) {
return null;
}
}

数据绑定(bind)

免费,现在你还有Android Data Binding为您的Map :

@Override
protected onCreate() {
mUserMap = new UserArrayMap();
mChangedCallback = new OnUserMapChanged();
}

@Override
protected void onResume() {
super.onResume();
mUserMap.addOnMapChangedCallback(mChangedCallback);
}

@Override
protected void onPause() {
mUserMap.removeOnMapChangedCallback(mChangedCallback);
super.onPause();
}

static class OnUserMapChanged extends OnMapChangedCallback<FirebaseArrayMap<String, User>, String, User> {

@Override
public void onMapChanged(FirebaseArrayMap<String, User> sender, String key) {
Log.e(TAG, key);
Log.e(TAG, sender.get(key).toString());
}

}

记得在 onResume 中(取消)注册您的回调和 onPause为了避免ChildEventListener引起的内存泄漏更新。

关于android - 如何使用数据绑定(bind)库将 Firebase 监听器转换为可观察 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41767616/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com