mirror of
https://github.com/emanuele-f/PCAPdroid.git
synced 2026-06-16 21:10:57 +08:00
Workaround for crash in RecyclerView dispatchLayout
In some rare cases the RecyclerView dispatchLayout crashes with an IndexOutOfBoundsException. This seems a bug in the androidx library. The provided workaround should fix it.
This commit is contained in:
parent
52af258a02
commit
12e4975e66
@ -112,7 +112,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
appIcon = ((app != null) && (app.getIcon() != null)) ? Objects.requireNonNull(app.getIcon().getConstantState()).newDrawable() : unknownIcon;
|
||||
icon.setImageDrawable(appIcon);
|
||||
|
||||
if(conn.info.length() > 0)
|
||||
if((conn.info != null) && (conn.info.length() > 0))
|
||||
remote.setText(conn.info);
|
||||
else
|
||||
remote.setText(conn.dst_ip);
|
||||
@ -249,12 +249,14 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
|
||||
@Override
|
||||
public void connectionsChanges(int num_connetions) {
|
||||
//Log.d(TAG, "connectionsChanges: " + num_connetions + " connections");
|
||||
mUnfilteredItemsCount = num_connetions;
|
||||
refreshFilteredConnections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionsAdded(int start, ConnectionDescriptor []conns) {
|
||||
//Log.d(TAG, "connectionsAdded: at " + start + ", " + conns.length + " connections");
|
||||
mUnfilteredItemsCount += conns.length;
|
||||
|
||||
if(mFilteredConn == null) {
|
||||
@ -281,6 +283,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
|
||||
@Override
|
||||
public void connectionsRemoved(int start, ConnectionDescriptor []conns) {
|
||||
//Log.d(TAG, "connectionsRemoved: at " + start + ", " + conns.length + " connections");
|
||||
mUnfilteredItemsCount -= conns.length;
|
||||
|
||||
if(mFilteredConn == null) {
|
||||
@ -306,6 +309,8 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
|
||||
@Override
|
||||
public void connectionsUpdated(int[] positions) {
|
||||
//Log.d(TAG, "connectionsUpdated: " + positions.length + " connections");
|
||||
|
||||
if(mFilteredConn == null) {
|
||||
for(int pos : positions)
|
||||
notifyItemChanged(pos);
|
||||
|
||||
@ -35,7 +35,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.emanuelef.remote_capture.CaptureService;
|
||||
import com.emanuelef.remote_capture.ConnectionsRegister;
|
||||
@ -78,8 +77,7 @@ public class AppsFragment extends Fragment implements ConnectionsListener {
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
mRecyclerView = view.findViewById(R.id.apps_stats_view);
|
||||
LinearLayoutManager layoutMan = new LinearLayoutManager(getContext());
|
||||
mRecyclerView.setLayoutManager(layoutMan);
|
||||
mRecyclerView.setLayoutManager(new EmptyRecyclerView.MyLinearLayoutManager(getContext()));
|
||||
|
||||
mAdapter = new AppsStatsAdapter(getContext());
|
||||
doRefreshApps();
|
||||
|
||||
@ -49,7 +49,6 @@ import androidx.appcompat.widget.SearchView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.emanuelef.remote_capture.AppsResolver;
|
||||
@ -174,7 +173,7 @@ public class ConnectionsFragment extends Fragment implements ConnectionsListener
|
||||
mFabDown = view.findViewById(R.id.fabDown);
|
||||
mRecyclerView = view.findViewById(R.id.connections_view);
|
||||
mOldConnectionsText = view.findViewById(R.id.old_connections_notice);
|
||||
LinearLayoutManager layoutMan = new LinearLayoutManager(requireContext());
|
||||
EmptyRecyclerView.MyLinearLayoutManager layoutMan = new EmptyRecyclerView.MyLinearLayoutManager(requireContext());
|
||||
mRecyclerView.setLayoutManager(layoutMan);
|
||||
mApps = new AppsResolver(requireContext());
|
||||
|
||||
@ -512,7 +511,7 @@ public class ConnectionsFragment extends Fragment implements ConnectionsListener
|
||||
}
|
||||
|
||||
private void recheckScroll() {
|
||||
final LinearLayoutManager layoutMan = (LinearLayoutManager) mRecyclerView.getLayoutManager();
|
||||
final EmptyRecyclerView.MyLinearLayoutManager layoutMan = (EmptyRecyclerView.MyLinearLayoutManager) mRecyclerView.getLayoutManager();
|
||||
assert layoutMan != null;
|
||||
int first_visibile_pos = layoutMan.findFirstCompletelyVisibleItemPosition();
|
||||
int last_visible_pos = layoutMan.findLastCompletelyVisibleItemPosition();
|
||||
|
||||
@ -27,7 +27,6 @@ import android.widget.Filterable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.emanuelef.remote_capture.adapters.AppsAdapter;
|
||||
import com.emanuelef.remote_capture.model.AppDescriptor;
|
||||
@ -57,7 +56,7 @@ public class AppsListView extends EmptyRecyclerView implements SearchView.OnQuer
|
||||
|
||||
private void initialize(Context context) {
|
||||
mAllApps = null;
|
||||
setLayoutManager(new LinearLayoutManager(context));
|
||||
setLayoutManager(new MyLinearLayoutManager(context));
|
||||
setHasFixedSize(true);
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
@ -31,6 +32,25 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
public class EmptyRecyclerView extends RecyclerView {
|
||||
private View mEmptyView;
|
||||
|
||||
/* Workaround for crash "java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:-1)".
|
||||
* See https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position .
|
||||
* It can be reproduced by setting CaptureService.CONNECTIONS_LOG_SIZE = 4 and triggering a rollover right after inserting
|
||||
* item 3 in the register. It may take several tries to reproduce.
|
||||
* Possibly related issues:
|
||||
* - https://issuetracker.google.com/issues?q=componentid:192731%2B%20IndexOutOfBoundsException%20Invalid%20item%20position
|
||||
* Another way to fix the issue is to disable the item animations via setItemAnimator(null).
|
||||
*/
|
||||
public static class MyLinearLayoutManager extends LinearLayoutManager {
|
||||
public MyLinearLayoutManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPredictiveItemAnimations() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EmptyRecyclerView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user