首页 > 解决方案 > Android arrayList does not perserve value when onChange is called

问题描述

I have the following observer to monitor a table change, when a change is trigger, it will call api to sync user information. This logic does the work but it happens that the OnChange call multiple time with same change set so it can make multiple api call which is not needed. I added a global list to capture inProcess items but the list is not synchronized between each of the OnChange call. Here is the code:

    userViewModel.getAllNewUsers().observe(getActivity(), new Observer<List<User>>() {
        @Override
        public void onChanged(@Nullable List<User> users) {
            Log.d(logTag, "Observeed " + users.size() + " new users, calling updateNewUsers");

            List<User> userSyncList = new ArrayList<>();

            Log.d(logTag, "userProcessingList size " + userProcessingList.size());
            Log.d(logTag, "users size " + users.size());

            if (userProcessingList.size() == 0 && users.size() > 0) {
                Log.d(logTag, "Nothing is processing, let's sync all users");
                userProcessingList.addAll(users);
                userSyncList.addAll(users);
                Log.d(logTag, "new userProcessingList size " + userProcessingList.size());
                Log.d(logTag, "userSyncList " + userProcessingList.toString());
            } else if (users.size() > 0) {
                for (User user : users) {
                    if (!userProcessingList.contains(user)) {

                        Log.d(logTag, "userProcessingList is " + userProcessingList.toString());
                        userProcessingList.add(user);
                        userSyncList.add(user);
                    } else {
                        Log.d(logTag, "User already in syncing process, ignoring...");
                    }
                }
            }

            if (userSyncList.size() > 0) {
                updateNewUsers(userSyncList);
            }

            if (users.size() == 0 && userProcessingList.size() > 0) {
                Log.d(logTag, "all users are in sync, let empty out the processing list");
                userProcessingList.clear();
            }

            Log.d(logTag, "at the end userProcessingList size " + userProcessingList.size());
        }

    });

here is the log

09-16 23:35:34.040 5956-5956: Observeed 0 new users, calling updateNewUsers

09-16 23:35:34.040 5956-5956: userProcessingList size 0

09-16 23:35:34.040 5956-5956: users size 0

09-16 23:35:34.040 5956-5956: at the end userProcessingList size 0

09-16 23:35:34.047 5956-5956: Observeed 2 new users, calling updateNewUsers

09-16 23:35:34.047 5956-5956: userProcessingList size 0

09-16 23:35:34.047 5956-5956: users size 2

09-16 23:35:34.048 5956-5956: Nothing is processing, let's sync all users

09-16 23:35:34.048 5956-5956: new userProcessingList size 2   <-- THE LIST SIZE IS NOW 2

09-16 23:35:34.048 5956-5956: in updateViewModelForNewUsers

09-16 23:35:34.048 5956-5956: newUserCounter is  -1

09-16 23:35:34.048 5956-5956: isVisible is true

09-16 23:35:34.050 5956-5956: at the end userProcessingList size 2   <-- THE LIST IS STILL 2

    09-16 23:35:34.050 5956-5956: Observeed 2 new users, calling updateNewUsers

    09-16 23:35:34.050 5956-5956: userProcessingList size 0   <-- LIST SIZE IS NOW 0 WHILE IT SHOULD BE 2

    09-16 23:35:34.050 5956-5956: users size 2

    09-16 23:35:34.050 5956-5956: Nothing is processing, let's sync all users

    09-16 23:35:34.050 5956-5956: new userProcessingList size 2

    09-16 23:35:34.050 5956-5956: in updateViewModelForNewUsers

    09-16 23:35:34.050 5956-5956: newUserCounter is  0

    09-16 23:35:34.050 5956-5956: isVisible is true

    The list size will eventually be 2 after couple OnChange is called.

I try CopyOnWriteArrayList, and collect.synchronizedList with Synchorized(userProcessingList){} and both do not help. Please advise!

标签: javaandroidarraylistandroid-livedata

解决方案


推荐阅读