Commit 8ff28698 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Another attemp to prevent app from crashing because of...

Another attemp to prevent app from crashing because of java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
parent ec1bb0b5
Pipeline #6123 passed with stages
in 1 minute and 40 seconds
...@@ -23,6 +23,7 @@ import android.content.Context; ...@@ -23,6 +23,7 @@ import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.recyclerview.widget.DiffUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
...@@ -74,14 +75,15 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> { ...@@ -74,14 +75,15 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
public void refresh() { public void refresh() {
ChatRoom[] rooms = LinphoneManager.getCore().getChatRooms(); ChatRoom[] rooms = LinphoneManager.getCore().getChatRooms();
List<ChatRoom> roomsList;
if (mContext.getResources().getBoolean(R.bool.hide_empty_one_to_one_chat_rooms)) { if (mContext.getResources().getBoolean(R.bool.hide_empty_one_to_one_chat_rooms)) {
mRooms = LinphoneUtils.removeEmptyOneToOneChatRooms(rooms); roomsList = LinphoneUtils.removeEmptyOneToOneChatRooms(rooms);
} else { } else {
mRooms = Arrays.asList(rooms); roomsList = Arrays.asList(rooms);
} }
Collections.sort( Collections.sort(
mRooms, roomsList,
new Comparator<ChatRoom>() { new Comparator<ChatRoom>() {
public int compare(ChatRoom cr1, ChatRoom cr2) { public int compare(ChatRoom cr1, ChatRoom cr2) {
long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime(); long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime();
...@@ -91,7 +93,10 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> { ...@@ -91,7 +93,10 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
} }
}); });
notifyDataSetChanged(); DiffUtil.DiffResult diffResult =
DiffUtil.calculateDiff(new ChatRoomDiffCallback(roomsList, mRooms));
diffResult.dispatchUpdatesTo(this);
mRooms = roomsList;
} }
public void clear() { public void clear() {
...@@ -114,4 +119,37 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> { ...@@ -114,4 +119,37 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
public long getItemId(int position) { public long getItemId(int position) {
return position; return position;
} }
class ChatRoomDiffCallback extends DiffUtil.Callback {
List<ChatRoom> oldChatRooms;
List<ChatRoom> newChatRooms;
public ChatRoomDiffCallback(List<ChatRoom> newRooms, List<ChatRoom> oldRooms) {
oldChatRooms = oldRooms;
newChatRooms = newRooms;
}
@Override
public int getOldListSize() {
return oldChatRooms.size();
}
@Override
public int getNewListSize() {
return newChatRooms.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
ChatRoom oldRoom = oldChatRooms.get(oldItemPosition);
ChatRoom newRoom = newChatRooms.get(newItemPosition);
return oldRoom.getLocalAddress().weakEqual(newRoom.getLocalAddress())
&& oldRoom.getPeerAddress().weakEqual(newRoom.getPeerAddress());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldChatRooms.get(oldItemPosition).equals(newChatRooms.get(newItemPosition));
}
}
} }
...@@ -267,7 +267,7 @@ public class ChatRoomsFragment extends Fragment ...@@ -267,7 +267,7 @@ public class ChatRoomsFragment extends Fragment
public void onContactsUpdated() { public void onContactsUpdated() {
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter(); ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
if (adapter != null) { if (adapter != null) {
adapter.notifyDataSetChanged(); adapter.refresh();
} }
} }
......
...@@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ...@@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.linphone.core.tools.Log;
/* https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position */ /* https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position */
public class LinphoneLinearLayoutManager extends LinearLayoutManager { public class LinphoneLinearLayoutManager extends LinearLayoutManager {
...@@ -46,4 +48,13 @@ public class LinphoneLinearLayoutManager extends LinearLayoutManager { ...@@ -46,4 +48,13 @@ public class LinphoneLinearLayoutManager extends LinearLayoutManager {
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);
} }
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
Log.w("[LinearLayoutManager] Index out of bounds exception successfully catched...");
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment