运行 ArrayAdapter 和 getView 中的 firebase 事务

running firebase transaction within ArrayAdapter and getView

你能运行 Array 适配器和 getView 中的 firebase 事务吗 ;

      public class upImgAdapter extends ArrayAdapter {

    public List<uploadedContentModels> upImgModelsList;
    private int resource;
    private LayoutInflater inflater;

    public upImgAdapter(Context context, int resource,
                        List<uploadedContentModels> objects) {
        super(context, resource, objects);
        upImgModelsList = objects;
        this.resource = resource;
        inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

    }

    /** getting the view ref. to be implemented in the listview & declaring layout elements **/

    @Override
    public View getView(int position, View convertView, ViewGroup parent){

        if(convertView == null){
            convertView = inflater.inflate(resource, null);
        }

        /** passing the image to the UIL **/

        ImageView imageViewDisplayMemebers;
        imageViewDisplayMemebers = (ImageView)convertView.findViewById(R.id.imageViewDisplayMemebers);

        ImageLoader.getInstance().displayImage(upImgModelsList.get(position).getAddress(), imageViewDisplayMemebers);
       final String imgToBeRatedRef = upImgModelsList.get(position).getPublic_id();

        RatingBar ratingBar;
        ratingBar = (RatingBar)convertView.findViewById(R.id.ratingBar);
        ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                newRatingImg = (ratingBar.getRating());
            }
        });

        Button buttonRatingSubm;
        buttonRatingSubm = (Button)convertView.findViewById(R.id.buttonRatingSubm);
        buttonRatingSubm.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v){
                final Firebase firebaseRefRating = new Firebase("https://cloudname.firebaseio.com//data/images/" + imgToBeRatedRef + "/rating");
                firebaseRefRating.runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {
                        int currentRating = (int) mutableData.getValue();
                        int updatedRating = (currentRating + newRatingImg);
                        mutableData.setValue(updatedRating);

                        return Transaction.success(mutableData);
                    }

                    @Override
                    public void onComplete(FirebaseError firebaseError, boolean b, DataSnapshot dataSnapshot) {

                    }
                });
            }
        });

            return convertView;

我面临的问题是,当我 运行 调试并点击按钮后,我看到执行从地址行跳转

   public Transaction.Result doTransaction(MutableData mutableData) {

到 getView 方法的结尾(在 return convertView 之后) 我尝试了几种方法,通过在点击监听器中传递一个方法(即 submitRating(); )并创建该方法并在其中传递相同的代码,并且发生了相同的行为,我还尝试在没有事务的情况下使用 setValue,并且同样的事情发生了!?

有人可以向我解释一下这种行为吗,是因为 Array Adapter 和 get view 还是我的代码有问题导致我无法发现!?

                  public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
               ratingNew[0] = (ratingBar.getRating());
            }
        });

        Button buttonRatingSubm;
        buttonRatingSubm = (Button)convertView.findViewById(R.id.buttonRatingSubm);
        buttonRatingSubm.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v){
                Log.e("myTag","Before doTransaction()");

                final Firebase firebaseRefRating = new Firebase("https://wi4x4.firebaseio.com//data/images");
                firebaseRefRating.child(imgToBeRatedRef).child("rating").runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {
                        Log.e("myTag","Inside doTransaction()");

                        int currentRating = (int) mutableData.getValue();
                        int updatedRating = (currentRating + ratingNew[0]);
                        mutableData.setValue(updatedRating);
                        Toast.makeText(getApplicationContext(),
                                "submitting rating"
                                , Toast.LENGTH_SHORT).show();
                        return Transaction.success(mutableData);
                    }

                    @Override
                    public void onComplete(FirebaseError firebaseError, boolean b, DataSnapshot dataSnapshot) {
                        if(firebaseError != null){
                            Log.e("myTag","After doTransaction()");

                            Toast.makeText(getApplicationContext(),
                                    "Rating Submitted"
                                    , Toast.LENGTH_SHORT).show();
                        }else {
                            Log.e("myTag","Error doTransaction()");

                            Toast.makeText(getApplicationContext(),
                                    "Error submitting rating failed"
                                    , Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        });

与 Firebase(以及一般的现代网络)中的许多操作一样,事务处理程序是异步调用的。您可以通过添加一些日志语句轻松地看到这一点:

final Firebase firebaseRefRating = new Firebase("https://cloudname.firebaseio.com//data/images/" + imgToBeRatedRef + "/rating");
System.out.println("Before runTransaction()");
firebaseRefRating.runTransaction(new Transaction.Handler() {
    public Transaction.Result doTransaction(MutableData mutableData) {
        System.out.println("Inside doTransaction()");
        int currentRating = (int) mutableData.getValue();
        int updatedRating = (currentRating + newRatingImg);
        mutableData.setValue(updatedRating);

        return Transaction.success(mutableData);
    }
    public void onComplete(FirebaseError firebaseError, boolean b, DataSnapshot dataSnapshot) {

    }
});
System.out.println("After runTransaction()");

与您预期的不同,输出将是:

Before runTransaction()

After runTransaction()

Inside doTransaction()

原因是,对于 运行 事务,Firebase 客户端可能需要调用它的服务器以获取该位置的当前值。这是一个异步操作。为了防止阻塞程序,客户端在 runTransaction() 调用 之后继续执行下一条语句 。然后当客户端确定当前值时,它会调用您的回调。