我有一个活动,在那些活动中,我有一个带有适配器的RecyclerView,它将基于AsyncTask onPostExecute加载。
这是代码。

public class AntamAddEditDetailBagsQueueIncomingActivity extends AppCompatActivity {

    public static final String EXTRA_ID = "com.tsurumaru.dzil.clientwarehouse.EXTRA_ID";

    RecyclerView recyclerView;
    BagLotNumberAdapter bagLotNumberAdapter;
    ArrayList<BagLotNumberModel> bagLotNumbers = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_antam_add_edit_detail_bags_queue_incoming);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);

        Intent intent = getIntent();

        long id = intent.getLongExtra(EXTRA_ID, -1);
        setTitle("Edit Bags " + intent.getLongExtra(EXTRA_ID, -1));

        recyclerView = findViewById(R.id.recyclerViewAntamIncomingScanQR);

        // Default is emtpy
        bagLotNumberAdapter = new BagLotNumberAdapter(this, bagLotNumbers);

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setAdapter(bagLotNumberAdapter);

        ItemTouchHelper itemTouchHelper = new
                ItemTouchHelper(new SwipeToDeleteBagLotNumberCallback(bagLotNumberAdapter));
        itemTouchHelper.attachToRecyclerView(recyclerView);

        // Run on Asynctask
        QueueIncomingRepository queueIncomingRepository = new QueueIncomingRepository(this, id);
        queueIncomingRepository.getAllJoinBag();
    }
}


本地仓库

public class QueueIncomingRepository {

    private Context context
    private Long idQueueIncoming;

    public QueueIncomingRepository(Context context, Long id) {
        AppDatabase database = AppDatabase.getInstance(context);
        queueIncomingDao = database.queueIncomingDao();

        this.context = context;
        this.idQueueIncoming = id;
    }

    // Asynctask
    public void getAllJoinBag() {
        new SelectWithBagsAsyncTask(context, queueIncomingDao).execute(idQueueIncoming);
    }

    // Inner Class
    private static class SelectWithBagsAsyncTask extends AsyncTask<Long, Void, List<QueueIncomingDao.QueueIncoming>> {

        private String TAG = "SelectBagAsync";
        private QueueIncomingDao queueIncomingDao;
        private Context context;

        private SelectWithBagsAsyncTask(Context context, QueueIncomingDao queueIncomingDao) {
            this.queueIncomingDao = queueIncomingDao;
            this.context = context;
        }

        @Override
        protected List<QueueIncomingDao.QueueIncoming> doInBackground(Long... longs) {
            return queueIncomingDao.getAllJoinBag(longs[0]);
        }

        @Override
        protected void onPostExecute(List<QueueIncomingDao.QueueIncoming> queueIncomings) {
            super.onPostExecute(queueIncomings);

            ArrayList<BagLotNumberModel> bagLotNumbers = new ArrayList<>();
            for (QueueIncomingDao.QueueIncoming queueIncoming : queueIncomings) {
                if (queueIncoming.getId() != null) {
                    bagLotNumbers.add(new BagLotNumberModel(
                            queueIncoming.getId(),
                            queueIncoming.getBagNumber(),
                            queueIncoming.getLotNumber(),
                            queueIncoming.getConsigneeName(),
                            queueIncoming.getAllocationConsignee(),
                            queueIncoming.getNettWeight(),
                            queueIncoming.getGrossWeight()
                    ));
                }
            }

            if (!bagLotNumbers.isEmpty()) {

                RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
                BagLotNumberAdapter bagLotNumberAdapter = new BagLotNumberAdapter(context, bagLotNumbers);
                recyclerView.setAdapter(bagLotNumberAdapter);

                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        // Update adapter
                        bagLotNumberAdapter.notifyDataSetChanged();

                    }
                });
            }
        }
    }
}


一切正确,但问题出在滑动删除上。
当AsyncTask中的bagLotNumberAdapter.notifyDataSetChanged();时,UI Thread中的Recylerview已更新,但是为什么大小仍为0?

java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    at java.util.ArrayList.get(ArrayList.java:308)
    at com.tsurumaru.dzil.clientwarehouse.adapters.antam.incoming.BagLotNumberAdapter.deleteItem(BagLotNumberAdapter.java:103)
    at com.tsurumaru.dzil.clientwarehouse.adapters.antam.incoming.SwipeToDeleteBagLotNumberCallback.onSwiped(SwipeToDeleteBagLotNumberCallback.java:38)
    at android.support.v7.widget.helper.ItemTouchHelper$4.run(ItemTouchHelper.java:712)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:160)
    at android.app.ActivityThread.main(ActivityThread.java:5541)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)


任何帮助,它表示赞赏。

最佳答案

您正在async任务的onPostExecute()方法中创建一个新适配器,而ItemTouchHelper仍引用在onCreate()方法中创建的先前适配器,这里:

onCreate() {
...
bagLotNumberAdapter = new BagLotNumberAdapter(this, bagLotNumbers);

            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
            recyclerView.setLayoutManager(mLayoutManager);
            recyclerView.setAdapter(bagLotNumberAdapter);

            ItemTouchHelper itemTouchHelper = new
                    ItemTouchHelper(new SwipeToDeleteBagLotNumberCallback(bagLotNumberAdapter));
            itemTouchHelper.attachToRecyclerView(recyclerView);
    ...
    }


并且,在您的onPostExecute()方法中:

onPostExecute() {
...
RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
                BagLotNumberAdapter bagLotNumberAdapter = new BagLotNumberAdapter(context, bagLotNumbers);
                recyclerView.setAdapter(bagLotNumberAdapter);
...
}


无需在onPostExecute()中创建新的适配器,而是在适配器类中定义一个类似于setData()的方法,该方法将一个旧数据替换为一个:

pubilc void setData(List newData){
this.list = newData
}


因此,您的onPostExecute()方法现在变为:

onPostExecute() {
...
 RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
                BagLotNumberAdapter bagLotNumberAdapter = (BagLotNumberAdapter )recyclerView.getAdapter();
bagLotNumberAdapter.setData(bagLotNumbers);
 ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        // Update adapter
                        bagLotNumberAdapter.notifyDataSetChanged();

                    }
                });
...
}

关于java - 使用AsyncTask成功更新RecyclerView,但Activity/UI线程中的Arraylist大小不变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56490818/

10-11 03:49