0

I am using a view pager with three tabs (three fragments). In one of these fragments I have a recycler view. The items in this recycler view get updated every 2 seconds from the web. When I first start up the app, the recycler view runs just fine. Even when navigating to different tabs or navigating out of my app with home button, it all works.

However when I close the app by using the backkey and then go into my app again, the recycler view is not updating anymore. It shows the status that it had when the app quit. I monitor the adapter via the console and it keeps on working with the correct data, only the recycler view doesn't show this. I tried all kinds of stuff to "reconnect" adapter and recycler view but it won't work. I am having this issue for days. Any idea for the cause of this problem? See the relevant code for troubleshooting. Thank you!

public class UserAreaFragment extends Fragment implements PopupMenu.OnMenuItemClickListener {

   private RecyclerView mRecyclerview;
   private UserAdapter mAdapter;
   private RecyclerView.LayoutManager mLayoutmanager;
   private Handler mainHandler = new Handler();



   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle      savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_user_area, container, false);

        ...

        mAdapter = new UserAdapter(getActivity(), UserDataSingleton.getUserList());
        mRecyclerview = root.findViewById(R.id.userListing);
        mRecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerview.setAdapter(mAdapter);

        mAdapter.setOnItemClickListener(new UserAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {

                ...

            }

        });


   }


//Somewhere in my method that receives the data from an online DB:

         UserDataSingleton.getUserList().clear();
         UserDataSingleton.getUserList().addAll(serverResponse);
         mainHandler.post(updateUi);


//And finally the updateUi method: this is essential just sorting and then notifydatasetchanged

Runnable updateUi = new Runnable() {
        @Override
        public void run() {

           Collections.sort(UserDataSingleton.getUserList(), new Comparator<UserItem>() {
            @Override
            public int compare(UserItem lhs, UserItem rhs) {
                // -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
                return Double.parseDouble(lhs.getmDistance()) > Double.parseDouble(rhs.getmDistance()) ? 1 : Double.parseDouble(lhs.getmDistance()) < Double.parseDouble(rhs.getmDistance()) ? -1 : 0;
            }
        });

        mAdapter.notifyDataSetChanged();

        }
    };



//and this is my Adapter:

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
    private UserAdapter.OnItemClickListener mListener;
    private Context mContext;
    private List<UserItem> mUserlist;

    public UserAdapter(Context context,List<UserItem> userList){
        mUserlist=userList;
        mContext = context;
    }


    public interface OnItemClickListener{
        void onItemClick(int position);
    }

    public void setOnItemClickListener(UserAdapter.OnItemClickListener listener) {
        this.mListener = listener;
    }




    public static class UserViewHolder extends RecyclerView.ViewHolder{
        public TextView mUsername;
        public TextView mDistance;

        public ImageView userIcon;
        public UserViewHolder(@NonNull View itemView, final UserAdapter.OnItemClickListener listener) {
            super(itemView);
            mUsername = itemView.findViewById(R.id.tvNearUsername);
            mDistance = itemView.findViewById(R.id.tvDistance);
            userIcon = itemView.findViewById(R.id.usericon);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null){
                        int position = getAdapterPosition();
                        if (position!= RecyclerView.NO_POSITION){
                            listener.onItemClick(position);
                        }
                    }
                }
            });
        }

    }


    @NonNull
    @Override
    public UserAdapter.UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View v= inflater.inflate(R.layout.user_item, parent, false);
        UserViewHolder uvh= new UserViewHolder(v,mListener);
        return uvh;
    }

    @Override
    public void onBindViewHolder(@NonNull UserAdapter.UserViewHolder holder, int position) {
        UserItem currentitem = mUserlist.get(position);

        holder.mUsername.setText(currentitem.getmNearUsername());
        if (currentitem.isArea()){
            holder.mDistance.setVisibility(View.INVISIBLE);
            holder.userIcon.setImageResource(R.drawable.ic_placeicon);

        }else{
            holder.mDistance.setVisibility(View.VISIBLE);
        }
        int distToNextTen = ((Integer.parseInt(currentitem.getmDistance())+5)/10)*10+10;
        holder.mDistance.setText("< "+distToNextTen+"m");
    }

    @Override
    public int getItemCount() {
        return mUserlist.size();
    }




}

I tried to only display the lines that affect the issue for better readability. If you need to see more code just let me know. Thankful for this great community!

(I think problem might be in connection with the main Handler not pointing to the correct view or maybe an issue with adapter-recyclerview connection but I can't find a solution tried so many things already)

Nick
  • 65
  • 8
  • "....it keeps on working with the correct data, only the recycler view doesn't show this" . You mean the network call is happening and the updated data is getting injected into the adapter? – Azhar92 Dec 13 '19 at 18:35
  • Yes. When I check the count of the adapter via console for example it is correct. However the recycler view is showing different. – Nick Dec 13 '19 at 18:42
  • Give this a look. Since you are using Handler to post updates and problem is coming when going back (pause) state, this might be relevant : https://stackoverflow.com/questions/8040280/how-to-handle-handler-messages-when-activity-fragment-is-paused – Azhar92 Dec 13 '19 at 18:43
  • Thanks but I think its a different issue. Also my handler thread is running perfectly fine after restarting the app. The updateUi is running, the adapter is injected with the correct data, only the recycler view doesn't seem to care. My workaround used to be to put "System.exit(0);" in the parent activities onDestroy. So the app was killed 100% and on restart everything worked fine again. But that leads to more problems in other fields and is not a very elegant solution. – Nick Dec 13 '19 at 18:52

1 Answers1

0

Ok I found the problem. It had something to do with my runnables and handlers not being declared within onCreate. Somehow that messed it up. I made a major reconstruction of my code to solve it so its hard to tell which line exactly was the problem but if you are facing a similar problem check that your runOnUi and handler declarations happen in the right places.

Nick
  • 65
  • 8