Android Индекс библиотеки подкачки вне связанного исключения - PullRequest
0 голосов
/ 12 июля 2020

Я реализую библиотеку подкачки в android, все работает нормально, если элементы всех страниц одинаковы. Когда размер элемента последней страницы равен 1, а не 10, возникает исключение. Я использую библиотеку подкачки 2.1.1 с androidx.

Exception

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dasfilm.azzeddine.dasfilm, PID: 22472
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
    at java.util.ArrayList.get(ArrayList.java:437)
    at androidx.paging.PagedStorage.get(PagedStorage.java:152)
    at androidx.paging.PagedList.get(PagedList.java:384)
    at androidx.paging.AsyncPagedListDiffer.getItem(AsyncPagedListDiffer.java:206)
    at androidx.paging.PagedListAdapter.getItem(PagedListAdapter.java:156)
    at com.dasfilm.azzeddine.dasfilm.Views.Adapters.FreshoneProductPaggingAdapter.onBindViewHolder(FreshoneProductPaggingAdapter.java:56)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
    at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:286)
    at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:343)
    at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:359)
    at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:366)
    at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:397)
    at android.os.Handler.handleCallback(Handler.java:907)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

Класс DataSource: это мой класс источника данных, который получает данные из веб-службы

public class MoviesInTheaterDataSource extends PageKeyedDataSource<Integer, FreshProduct> {
private static final String TAG = "MoviesInTheaterDataSou";
private ProductApiCall tmdbWebService;
private MutableLiveData<NetworkState> networkState;
private MutableLiveData<NetworkState> initialLoading;
private Executor retryExecutor;

public MoviesInTheaterDataSource(Executor retryExecutor,ProductApiCall webService) {
    tmdbWebService = webService;
    networkState = new MutableLiveData<>();
    initialLoading = new MutableLiveData<>();
    this.retryExecutor = retryExecutor;
}

public MutableLiveData<NetworkState> getNetworkState() {
    return networkState;
}

public MutableLiveData getInitialLoading() {

    return initialLoading;
}

@Override
public void loadInitial(@NonNull final LoadInitialParams<Integer> params, @NonNull final LoadInitialCallback<Integer, FreshProduct> callback) {
    Log.d(TAG, "loadInitial: ");
    initialLoading.postValue(NetworkState.LOADING);
    networkState.postValue(NetworkState.LOADING);

    tmdbWebService.getProductList(1,"","",1);


    tmdbWebService.SetListenersProduct(new ProductApiCall.ListenersProduct() {
        @Override
        public void onSuccess(List<FreshProduct> itemList, int totalPageCount) {
            initialLoading.postValue(NetworkState.LOADING);
            int loadsize = params.requestedLoadSize;
            callback.onResult(itemList, 1, 2);

            networkState.postValue(NetworkState.LOADED);

        }
    });




}

@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, FreshProduct> callback) {

}

@Override
public void loadAfter(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, FreshProduct> callback) {
    networkState.postValue(NetworkState.LOADING);




    tmdbWebService.getProductList(1,"","",params.key);


    tmdbWebService.SetListenersProduct(new ProductApiCall.ListenersProduct() {
        @Override
        public void onSuccess(List<FreshProduct> itemList, int totalPageCount) {
            initialLoading.postValue(NetworkState.LOADING);
                     networkState.postValue(NetworkState.LOADED);

            callback.onResult(itemList, params.key+1);


            networkState.postValue(NetworkState.LOADED);
        }
    });
}

}

Класс DataSource Factory

public class MoviesInTheaterDataSource extends PageKeyedDataSource<Integer, FreshProduct> {
private static final String TAG = "MoviesInTheaterDataSou";
private ProductApiCall tmdbWebService;
private MutableLiveData<NetworkState> networkState;
private MutableLiveData<NetworkState> initialLoading;
private Executor retryExecutor;

public MoviesInTheaterDataSource(Executor retryExecutor,ProductApiCall webService) {
    tmdbWebService = webService;
    networkState = new MutableLiveData<>();
    initialLoading = new MutableLiveData<>();
    this.retryExecutor = retryExecutor;
}

public MutableLiveData<NetworkState> getNetworkState() {
    return networkState;
}

public MutableLiveData getInitialLoading() {

    return initialLoading;
}

@Override
public void loadInitial(@NonNull final LoadInitialParams<Integer> params, @NonNull final LoadInitialCallback<Integer, FreshProduct> callback) {
    Log.d(TAG, "loadInitial: ");
    initialLoading.postValue(NetworkState.LOADING);
    networkState.postValue(NetworkState.LOADING);

    tmdbWebService.getProductList(1,"","",1);


    tmdbWebService.SetListenersProduct(new ProductApiCall.ListenersProduct() {
        @Override
        public void onSuccess(List<FreshProduct> itemList, int totalPageCount) {
            initialLoading.postValue(NetworkState.LOADING);
            int loadsize = params.requestedLoadSize;
            callback.onResult(itemList, 1, 2);

            networkState.postValue(NetworkState.LOADED);

        }
    });




}

@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, FreshProduct> callback) {

}

@Override
public void loadAfter(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, FreshProduct> callback) {
    networkState.postValue(NetworkState.LOADING);




    tmdbWebService.getProductList(1,"","",params.key);


    tmdbWebService.SetListenersProduct(new ProductApiCall.ListenersProduct() {
        @Override
        public void onSuccess(List<FreshProduct> itemList, int totalPageCount) {
            initialLoading.postValue(NetworkState.LOADING);
                     networkState.postValue(NetworkState.LOADED);

            callback.onResult(itemList, params.key+1);


            networkState.postValue(NetworkState.LOADED);
        }
    });
}

}

Класс ViewModel

public class MoviesInTheaterViewModel extends ViewModel {
private static final String TAG = "TheaterViewModel";
private LiveData<PagedList<FreshProduct>> moviesInTheaterList;
private LiveData<NetworkState> networkStateLiveData;
private Executor executor;
private LiveData<MoviesInTheaterDataSource> dataSource;


public MoviesInTheaterViewModel() {
    Log.d(TAG, "MoviesInTheaterViewModel: ");
    executor = Executors.newFixedThreadPool(5);
    ProductApiCall webService = new ProductApiCall(MyApp.getInstance().getApplicationContext());
    MoviesInTheaterDataSourceFactory factory = new MoviesInTheaterDataSourceFactory(executor,webService);


    dataSource =  factory.getMutableLiveData();

    networkStateLiveData = Transformations.switchMap(factory.getMutableLiveData(), new Function<MoviesInTheaterDataSource, LiveData<NetworkState>>() {
        @Override
        public LiveData<NetworkState> apply(MoviesInTheaterDataSource source) {
            Log.d(TAG, "apply: network change");
            return source.getNetworkState();
        }
    });

    PagedList.Config pageConfig = (new PagedList.Config.Builder())
            .setEnablePlaceholders(false)
            .setPageSize(10)
            .build();

    moviesInTheaterList = (new LivePagedListBuilder<Integer,FreshProduct>(factory,pageConfig))
                                                .setFetchExecutor(executor)
                                                .build();

}

public LiveData<PagedList<FreshProduct>> getMoviesInTheaterList() {
    Log.d(TAG, "getMoviesInTheaterList: ");
    return moviesInTheaterList;
}

public LiveData<NetworkState> getNetworkStateLiveData() {
    return networkStateLiveData;
}

}

Класс активности

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private MoviesInTheaterViewModel mMoviesViewModel;
private RecyclerView mRecyclerView;
private FreshoneProductPaggingAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate: ");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mRecyclerView = findViewById(R.id.list);

    adapter = new FreshoneProductPaggingAdapter(this);

    mMoviesViewModel = ViewModelProviders.of(this).get(MoviesInTheaterViewModel.class);
    mMoviesViewModel.getMoviesInTheaterList().observe(this, new Observer<PagedList<FreshProduct>>() {
        @Override
        public void onChanged(@Nullable PagedList<FreshProduct> movies) {
            Log.d(TAG, "onChanged: "+movies.size());
            adapter.submitList(movies);
        }
    });
    mMoviesViewModel.getNetworkStateLiveData().observe(this, new Observer<NetworkState>() {
        @Override
        public void onChanged(@Nullable NetworkState networkState) {
            Log.d(TAG, "onChanged: network state changed");
            adapter.setNetworkState(networkState);
        }
    });
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
    mRecyclerView.setAdapter(adapter);
}

}

1 Ответ

0 голосов
/ 16 июля 2020

Paging2 не поддерживает переменные размеры страниц, вам необходимо перейти на Paging3 (все еще в альфа-версии) для этой функции. Частично это связано с тем, как была реализована поддержка листов, но Paging3 переписал все с нуля, чтобы удалить это ограничение.

...