Android Studio中相互依赖的回调函数-一个更优雅的解决方案
我的应用程序中有两个回调函数,其中一个需要另一个的结果,所以我希望它们异步执行。情况是这样的:Android Studio中相互依赖的回调函数-一个更优雅的解决方案,android,firebase,asynchronous,callback,android-asynctask,Android,Firebase,Asynchronous,Callback,Android Asynctask,我的应用程序中有两个回调函数,其中一个需要另一个的结果,所以我希望它们异步执行。情况是这样的: 我使用FirebaseInstanceId.getInstance().getInstanceId()获取设备的令牌。这是第一次回叫 当我拥有令牌时,我使用它访问Firebase实时数据库以获取用户的数据。这是第二次回叫 在我当前的解决方案中,我在doInBackground函数中使用带有信号量的AsyncTask,如下所示: private class AsyncOp extends AsyncTa
FirebaseInstanceId.getInstance().getInstanceId()
获取设备的令牌。这是第一次回叫doInBackground
函数中使用带有信号量的AsyncTask
,如下所示:
private class AsyncOp extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
final Semaphore semaphore = new Semaphore(0);
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
token = instanceIdResult.getToken();
JSONObject requestObject = new JSONObject();
try {
requestObject.put("token", token);
semaphore.release();
} catch (JSONException e) {
Log.e(TAG_MAINACTIVITY, token);
semaphore.release();
}
JsonObjectRequest req = new JsonObjectRequest(Request.Method.POST, REQUEST_URL + "token",
requestObject, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(TAG_MAINACTIVITY, "Token saved successfully");
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG_MAINACTIVITY, "Failed to save token - " + error);
}
});
_queue.add(req);
}
});
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
return token;
}
@Override
protected void onPostExecute(String token) {
getUser(token);
}
}
public void getUser(String token) {
db.child("users").child(token).addListenerForSingleValueEvent(new ValueEventListener() {
@SuppressLint("SetTextI18n")
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
// Navigate to fragment where new users can sign up:
goToSignup();
} else {
currentUser = dataSnapshot.getValue(User.class);
assert currentUser != null;
updateHeadline(currentUser.getName()); // Update UI to display the user's name
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG_MAINACTIVITY, databaseError.getMessage());
}
});
}
它工作得很好,但我忍不住觉得我错过了这里的全部要点,我可以使用一个更好的解决方案。我已经搜索了其他处理类似问题的StackOverflow问题,并找到了一些建议,但我在尝试实现这些问题时陷入了困境,对于这整个考验来说都是全新的(这实际上是我的第一个“真正的”项目)。我试着寻找一种像承诺
一样有效的东西,并找到了未来
,但我可能没有正确地完成它,因为它不起作用。这是唯一对我有效的解决方案,而不是简单地将getUser(token)
嵌套在第一个回调中。因此,如果您有任何适合我的想法,我很高兴听到。Firebase在主线程之外执行所有网络和磁盘I/O。这意味着很少有理由在后台任务中运行Firebase交互
除此之外,使用信号量时,流程要复杂得多。我会考虑把这个调用放到一个用户前面的调用的完成处理程序中。
合并后的结果是:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
token = instanceIdResult.getToken();
JSONObject requestObject = new JSONObject();
requestObject.put("token", token);
JsonObjectRequest req = new JsonObjectRequest(Request.Method.POST, REQUEST_URL + "token",
requestObject, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(TAG_MAINACTIVITY, "Token saved successfully");
getUser(token);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG_MAINACTIVITY, "Failed to save token - " + error);
}
});
_queue.add(req);
}
});
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时公共无效(InstancedResult InstancedResult){
token=instanceIdResult.getToken();
JSONObject requestObject=新的JSONObject();
requestObject.put(“token”,token);
JsonObjectRequest req=新的JsonObjectRequest(Request.Method.POST,Request_URL+“token”,
requestObject,新的Response.Listener(){
@凌驾
公共void onResponse(JSONObject响应){
Log.i(TAG_main活动,“令牌成功保存”);
获取用户(令牌);
}
},
新的Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
Log.e(TAG_MAINACTIVITY,“未能保存令牌-”+错误);
}
});
_队列添加(req);
}
});
谢谢Frank:)这实际上是我最初做的,但我认为最好避免嵌套函数。谢谢
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
token = instanceIdResult.getToken();
JSONObject requestObject = new JSONObject();
requestObject.put("token", token);
JsonObjectRequest req = new JsonObjectRequest(Request.Method.POST, REQUEST_URL + "token",
requestObject, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(TAG_MAINACTIVITY, "Token saved successfully");
getUser(token);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG_MAINACTIVITY, "Failed to save token - " + error);
}
});
_queue.add(req);
}
});