Android Studio中相互依赖的回调函数-一种更优雅的解决方案

问题描述 投票:0回答:1

我的应用程序中有2个回调函数,其中一个需要另一个函数的结果,因此我希望它们异步执行。场景是这样的:

  1. 我用FirebaseInstanceId.getInstance().getInstanceId()获取设备的令牌。这是第一个回调。

  2. 当我拥有令牌时,我将其用于访问Firebase Realtime DB以获取用户的数据。这是第二个回调。

在当前解决方案中,我将AsyncTaskSemaphore函数中的doInBackground结合使用,如下所示:

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();

效果很好,但我忍不住想念这里的要点,并且有一个更好的解决方案可以使用。我已经搜索了处理类似问题的其他StackOverflow问题,并找到了一些建议,但是我却纠结于尝试实施它们,这对整个苦难来说还是很新的(实际上是我的第一个“真实”项目)。我尝试寻找可以像Promise一样工作的东西,但发现Future,但是由于它不起作用,我可能做得不好。这是唯一对我有用的解决方案,除了简单地将getUser(token)嵌套在第一个回调中。因此,如果您有任何对我有用的想法,我将很高兴听到。

android firebase asynchronous callback android-asynctask
1个回答
0
投票
除此之外,当使用信号灯时,流程要复杂得多。我会考虑只将呼叫吸引到先前呼叫的完成处理程序中。

合并成:

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); } });

© www.soinside.com 2019 - 2024. All rights reserved.