如何异步设置 recyclerView 适配器
How to Set recyclerView adapter asynchronously
我写了一个 class,它在文件夹中查找特定文件并将它们的地址(加上 3 个其他属性)保存到共享首选项,然后在我的自定义适配器中调用一个方法(方法(名为 getAllItems)从共享首选项中读取数据,实例化新的自定义对象并将它们添加到列表和 returns 列表中。这是最大的部分加载发生)然后适配器使用该项目列表从每个项目中检索地址,生成位图并将它们显示在 recyclerView 中
这是我得到的错误:
E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.amir.example, PID: 4968
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:787)
at java.util.HashMap$KeyIterator.next(HashMap.java:814)
at com.android.internal.util.XmlUtils.writeSetXml(XmlUtils.java:355)
at com.android.internal.util.XmlUtils.writeValueXml(XmlUtils.java:693)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:300)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:269)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:235)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:192)
at android.app.SharedPreferencesImpl.writeToFile(SharedPreferencesImpl.java:600)
at android.app.SharedPreferencesImpl.-wrap2(SharedPreferencesImpl.java)
at android.app.SharedPreferencesImpl.run(SharedPreferencesImpl.java:515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
现在,当文件数量很少(例如 100 个文件中有 20 个匹配)时,应用程序可以正常运行,但是当文件数量过多(例如 8000 个文件中有 200 个项目)时,应用程序会崩溃
我尝试将项目异步加载到适配器中:这在 MainActivity.java
中
public class AsyncAdapter extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
//This line will load the files into shared preferences (DataSource is my sharedPreferences)
Loader.loadPhoneStickers(adapter.getDataSource());
//this will cause the list that the adapter is attached to, to get updated and load all the items that were added to shared preferences
//this method will make a call to getAllItems and notifyItemRangeChanged
adapter.refresh();
return null;
}
}
但是无论我是异步设置适配器(设置适配器会导致所有加载发生)还是同步设置适配器,错误都一样
我应该在哪里加载?
otto 会有帮助吗?
您需要在 asynctask 中覆盖此方法,并在 ui 线程上运行的 postexecute 中覆盖此方法。您无法从 ui 线程刷新适配器。
public class AsyncAdapter extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
//This line will load the files into shared preferences (DataSource is my sharedPreferences)
Loader.loadPhoneStickers(adapter.getDataSource());
//this will cause the list that the adapter is attached to, to get updated and load all the items that were added to shared preferences
//this method will make a call to getAllItems and notifyItemRangeChanged
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter.refresh();
}
}
通常,当您在不同的线程中工作时,您无法与 ui 元素交互。通常的做法是在 Asynctask.Post 中使用 postExecute execute 在 doInbackground 完成后立即调用,并在 UI 线程上调用,您可以在其中执行所有 Ui 相关的事情。
我写了一个 class,它在文件夹中查找特定文件并将它们的地址(加上 3 个其他属性)保存到共享首选项,然后在我的自定义适配器中调用一个方法(方法(名为 getAllItems)从共享首选项中读取数据,实例化新的自定义对象并将它们添加到列表和 returns 列表中。这是最大的部分加载发生)然后适配器使用该项目列表从每个项目中检索地址,生成位图并将它们显示在 recyclerView 中 这是我得到的错误:
E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.amir.example, PID: 4968
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:787)
at java.util.HashMap$KeyIterator.next(HashMap.java:814)
at com.android.internal.util.XmlUtils.writeSetXml(XmlUtils.java:355)
at com.android.internal.util.XmlUtils.writeValueXml(XmlUtils.java:693)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:300)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:269)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:235)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:192)
at android.app.SharedPreferencesImpl.writeToFile(SharedPreferencesImpl.java:600)
at android.app.SharedPreferencesImpl.-wrap2(SharedPreferencesImpl.java)
at android.app.SharedPreferencesImpl.run(SharedPreferencesImpl.java:515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
现在,当文件数量很少(例如 100 个文件中有 20 个匹配)时,应用程序可以正常运行,但是当文件数量过多(例如 8000 个文件中有 200 个项目)时,应用程序会崩溃
我尝试将项目异步加载到适配器中:这在 MainActivity.java
中 public class AsyncAdapter extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
//This line will load the files into shared preferences (DataSource is my sharedPreferences)
Loader.loadPhoneStickers(adapter.getDataSource());
//this will cause the list that the adapter is attached to, to get updated and load all the items that were added to shared preferences
//this method will make a call to getAllItems and notifyItemRangeChanged
adapter.refresh();
return null;
}
}
但是无论我是异步设置适配器(设置适配器会导致所有加载发生)还是同步设置适配器,错误都一样
我应该在哪里加载? otto 会有帮助吗?
您需要在 asynctask 中覆盖此方法,并在 ui 线程上运行的 postexecute 中覆盖此方法。您无法从 ui 线程刷新适配器。
public class AsyncAdapter extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
//This line will load the files into shared preferences (DataSource is my sharedPreferences)
Loader.loadPhoneStickers(adapter.getDataSource());
//this will cause the list that the adapter is attached to, to get updated and load all the items that were added to shared preferences
//this method will make a call to getAllItems and notifyItemRangeChanged
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter.refresh();
}
}
通常,当您在不同的线程中工作时,您无法与 ui 元素交互。通常的做法是在 Asynctask.Post 中使用 postExecute execute 在 doInbackground 完成后立即调用,并在 UI 线程上调用,您可以在其中执行所有 Ui 相关的事情。