Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Studio中相互依赖的回调函数-一个更优雅的解决方案_Android_Firebase_Asynchronous_Callback_Android Asynctask - Fatal编程技术网

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()
    获取设备的令牌。这是第一次回叫

  • 当我拥有令牌时,我使用它访问Firebase实时数据库以获取用户的数据。这是第二次回叫

  • 在我当前的解决方案中,我在
    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);
        }
    });