gpt4 book ai didi

android - 从 AsyncTask 的事务访问 Firebase 数据库

转载 作者:行者123 更新时间:2023-11-29 19:32:29 25 4
gpt4 key购买 nike

我需要从正在进行事务的异步任务访问 Firebase 数据库。

所以我的设置是,我有一个 AsyncTask。在其 doInBackground 方法中,我调用了另一个方法,其中包含我运行事务的逻辑。在交易的 doTransaction 方法中,我需要从不同的路径访问数据并生成新数据(比如一些统计数据)。

看起来像这样:

public class MyAsyncTask extends AsyncTask<String,Void,Void> {

@Override
protected Void doInBackground(String... params) {
String para1 = params[0];
String para2 = params[1];

performCalculations(para1,para2);

return null;
}

public void performCalculation(String para1, String para2) {
DatbaseReference ref = FirebaseDatabase.getInstance().getReference().child(para1);

// Run the transaction here
ref.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {

TaskCompletionSource<DataSnapshot> taskCompletionSource = new TaskCompletionSource<>();

DatabaseReference ref2 = FirebaseDatabase.getInstance().getReference().child(param2);

ref2.addListenerForSingleValueEvent(new MyValueEventListener(taskCompletionSource));

try {
dataSnapshot = Tasks.await(taskCompletionSource.getTask());

// DOING SOME AWESOME THINGS HERE
// And updating the mutable Data


} catch (ExecutionException | InterruptedException e) {
Log.v(TAG, "Exception Catched");
e.printStackTrace();
}


mutableData.setValue(stats);
return Transaction.success(mutableData);
}

@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
if (databaseError != null) {
Log.d(TAG, "onComplete: Error: " + databaseError.getMessage());
} else {
Log.d(TAG, "onComplete: Transaction was successful");

}
}

}
}

private class MyValueEventListener implements ValueEventListener {

private final TaskCompletionSource<DataSnapshot> taskSource;

public MyValueEventListener(TaskCompletionSource<DataSnapshot> taskSource) {
this.taskSource = taskSource;
}

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.v(TAG, "Looks like MyValueEventListener received the data");
taskSource.setResult(dataSnapshot);
}

@Override
public void onCancelled(DatabaseError databaseError) {
Log.v(TAG, "Looks like MyValueEventListener thrown an error");
taskSource.setException(databaseError.toException());
}

}

}

到处都是日志,我遇到了它到达 Tasks.await 语句。但是 onDataChanged 回调永远不会被调用。

它卡在了那个点上。没有错误。没有异常(exception)。

最大的问题是,从那时起,它会停止整个应用程序的所有回调。我的所有 Activity 都被阻止,因为它从不调用 onDataChanged。看起来它在内部崩溃或被线程阻塞。

这是怎么回事?谢谢。

编辑:

因此,为了从交易中的 ref 获取最新数据,我将变量部分作为类的一部分。并将值事件监听器附加到它。所以它会一直保持更新。但是,如果离线排队事务将在触发值事件监听器之前开始运行怎么办?离线一段时间后上线后,有什么优先级先执行吗?

这是我更新后的代码:

public class MyAsyncTask extends AsyncTask<String,Void,Void> {

DataSnapshot mDataSnapshot;

ValueEventListener mListener;

DatabaseReference ref2;

@Override
protected Void doInBackground(String... params) {
String para1 = params[0];
String para2 = params[1];

performCalculations(para1,para2);

return null;
}

public void performCalculation(String para1, String para2) {

TaskCompletionSource<DataSnapshot> taskCompletionSource = new TaskCompletionSource<>();

ref2 = FirebaseDatabase.getInstance().getReference().child(param2);

ref2.addListenerForSingleValueEvent(new MyValueEventListener(taskCompletionSource));

try {
// Get the data first time before you proceed
dataSnapshot = Tasks.await(taskCompletionSource.getTask());

} catch (ExecutionException | InterruptedException e) {
Log.v(TAG, "Exception Catched");
e.printStackTrace();
}

// Register the value event listener to keep the data updated
mListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
mDataSnapshot = dataSnapshot
Log.v(TAG, "Data updated");
}

@Override
public void onCancelled(DatabaseError databaseError) {

}
};

ref2.addValueEventListener(mListener);


DatbaseReference ref = FirebaseDatabase.getInstance().getReference().child(para1);

// Run the transaction here
ref.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {

// Perform some stuff based on mDataSanpshot



mutableData.setValue(stats);
return Transaction.success(mutableData);
}

@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
if (databaseError != null) {
Log.d(TAG, "onComplete: Error: " + databaseError.getMessage());
} else {
Log.d(TAG, "onComplete: Transaction was successful");
ref2.removeEventListener(mListener);
}
}

}
}

// My value event listener here ...

}

最佳答案

您可能会从 Firebaser 那里得到更明智的答案,例如 FvP。在那之前,我敢肯定您在 runTransaction() 中等待的任务会造成死锁。您可以使用类似于此的 Log 语句查看回调运行的线程:

Log.i(TAG, "doTransaction: " + Thread.currentThread().getName());

doTransaction()FirebaseDatabaseWorker 线程上运行。监听器回调在主 (UI) 线程上运行,并且(我猜)由从数据库工作线程调度的事件驱动。

阻塞数据库工作线程将导致监听器回调永远不会触发。任务永远不会完成,因此永远不会释放 Task.await()

关于android - 从 AsyncTask 的事务访问 Firebase 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39725502/

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