Android Studio中相互依赖的回调函数——更优雅的解决方案
Posted
技术标签:
【中文标题】Android Studio中相互依赖的回调函数——更优雅的解决方案【英文标题】:Callback functions that depend on one another in Android Studio - a more elegant solution 【发布时间】:2020-09-15 16:39:32 【问题描述】:我的应用中有 2 个回调函数,其中一个需要另一个的结果,所以我希望它们异步执行。场景是这样的:
我使用FirebaseInstanceId.getInstance().getInstanceId()
获取设备的令牌。这是第一次回调。
获得令牌后,我会使用它来访问 Firebase 实时数据库以获取用户数据。这是第二次回调。
在我当前的解决方案中,我在doInBackground
函数中使用AsyncTask
和Semaphore
,如下所示:
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());
);
在我的OnCreate
中执行如下:
_queue = Volley.newRequestQueue(this);
AsyncOp getToken = new AsyncOp();
getToken.execute();
它工作得很好,但我不禁觉得我错过了这里的全部要点,我可以使用更好的解决方案。我已经搜索了处理类似问题的其他 *** 问题并找到了一些建议,但我在尝试实施它们时陷入了纠结,对这整个考验来说是相当新的(这实际上是我的第一个“真正的”项目)。我尝试寻找可以像Promise
一样工作的东西,并找到了Future
,但我可能没有正确地做到这一点,因为它不起作用。这是唯一对我有用的解决方案,而不是简单地将getUser(token)
嵌套在第一个回调中。因此,如果您有任何适合我的想法,我会很高兴听到。
【问题讨论】:
【参考方案1】: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);
);
【讨论】:
感谢 Frank :) 这实际上是我最初所做的,但我认为最好避免嵌套函数。谢谢。以上是关于Android Studio中相互依赖的回调函数——更优雅的解决方案的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有Android Studio的情况下编译JNI共享库,并在[关闭]中编译依赖项
Android -- 每日一问:回调函数和观察者模式的区别?
如何将 Flash builder 项目作为库包含在 android Studio 中?
更新 Visual Studio 2017,现在出现编译错误 C7510:“回调”:使用依赖模板名称必须以“模板”为前缀