我需要一种安全的做法来从数据库加载数据。 我需要从 Sql 数据库加载数据并将其放入列表或 recylerview 中。 所以我尝试了,我创建了一个类,每次当用户到达列表末尾时,它都会调用方法加载更多。而且它加载的数据有限。 就像“选择 * 从其中 1 限制 listItemCount,20”。 我遇到了这个问题,因为正在加载的线程以相同的计数值启动了两次。我已经将其更改为从加载线程同步全局运行方法。并从列表的后台工作人员访问计数。这对我帮助很大,并且数据已正确加载,但我仍然遇到问题。因为我需要从后台线程将数据插入listview,因为之后在主线程中进行同步和调用notify。如果我不这样做,我仍然会遇到问题。
- 线程 A:开始工作。
- 线程 B:WAITING完成线程 A(已同步)
- 线程 A:runOnUiThread() 尝试填充数据。
- 线程 B:允许运行代码,从 listView 获取计数。
- 线程 B:获得与 A 相同的计数,因为 A 未完成插入 声明。
- 话题 A:已添加数据。
- 线程 B:添加了相同的数据。
在此之后,我添加了一个atomicboolean,如果线程正在运行,他就不会被执行。这样它就可以完美工作,但有时您必须向上和向下滚动一点才能触发更多负载。 我认为这个解决方案对我来说有点脏。现在有人如何根据 ListView 的列表大小在后台线程中加载数据而不出现此问题?
到达列表末尾时调用此方法:
private ExecutorService executorService;
private void loadMore()
{
if(!isAdded())
return;
if(executorService == null)
executorService = Executors.newSingleThreadExecutor();
executorService.execute(new AsyncLoadMoreHashTags(getContext(), this, esaphTagAdapterVertical));
}
后台线程:
public class AsyncLoadMoreHashTags extends MyDataLoaderClass
{
private static final Object obLock = new Object();
public AsyncLoadMoreHashTags(Context context, DataBaseLoadWaiter dataBaseLoadWaiter, SpecialRecylerView spRecylerView)
{
super(context, dataBaseLoadWaiter, spRecylerView);
}
@Override
public void run()
{
super.run();
synchronized (AsyncLoadMoreHashTags.obLock)
{
List<Object> objectList = null;
try
{
int startFrom = super.getStartFrom()[0];
SQLHashtags sqlHashtags = new SQLHashtags(super.getSoftReferenceContext().get());
if(startFrom <= 0)
{
objectList = sqlHashtags.getMostUsedHashtags();
}
else
{
objectList = sqlHashtags.getAllHashtagLimited(startFrom);
}
sqlHashtags.close();
}
catch (Exception ec)
{
Log.i(getClass().getName(), "AsyncLoadMoreHashTags run() failed: " + ec);
}
finally
{
publish(objectList);
}
}
}
}
我需要的是,一次只启动一个线程。 有人有想法吗?
最佳答案
首先使用你应该使用 PagedList google提供的库,用于实现分页功能,如果您想使用后台线程进行数据库操作,可以使用Anko common 来执行此操作。这是一个例子,
internal val pagedList by lazy {
runBlocking { // Coroutine Context
withContext(Dispatchers.IO) {
// Read from database, and it will be initialised in background
}
}
}
如果您想要在 UI 上调度但在后台执行线程中执行某些操作,则执行此 doAsync 操作,然后返回使用自定义接口(interface)在 uiThread 中获取数据。
doAsync {
// LONG OPERATION
Thread.sleep(2000)
uiThread {
callback.onActionsDone(dataList)
}
}
如果您需要更多帮助,请告诉我。
关于Android从数据库异步获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54902501/