我曾经在github示例项目中遇到过这个AppExecutors类,但是我忘了在哪里。我发现它非常方便,因为它为我提供了多线程功能。但是我不确定在以下情况下是否可以正确执行Fragment中的代码:
我是否需要像下面所做的那样,将adapter.refreshData(list);
部分显式地包入主线程Runnable?
AppExecutors.java
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class AppExecutors {
private final Executor mDiskIO;
private final Executor mNetworkIO;
private final Executor mMainThread;
private static volatile AppExecutors mInstance;
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
this.mDiskIO = diskIO;
this.mNetworkIO = networkIO;
this.mMainThread = mainThread;
}
public static AppExecutors getInstance() {
if (mInstance == null) {
synchronized (AppExecutors.class) {
mInstance = new AppExecutors();
}
}
return mInstance;
}
private AppExecutors() {
this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}
public Executor diskIO() {
return mDiskIO;
}
public Executor networkIO() {
return mNetworkIO;
}
public Executor mainThread() {
return mMainThread;
}
public static void xDisk(@NonNull Runnable command) {
getInstance().diskIO().execute(command);
}
public static void xNet(@NonNull Runnable command) {
getInstance().networkIO().execute(command);
}
public static void xMain(@NonNull Runnable command) {
getInstance().mainThread().execute(command);
}
private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
@Override
public void execute(@NonNull Runnable command) {
mainThreadHandler.post(command);
}
}
}
SomeFragment.java
...
void setUpRecyclerView() {
TimeAllowedAdapter adapter = new TimeAllowedAdapter(getContext(), new ArrayList<>());
rcView.setAdapter(adapter);
rcView.setLayoutManager(new LinearLayoutManager(getContext()));
// then fetch data and refresh list
AppExecutors.xDisk(() -> {
List<TimeAllowed> list = AppDatabase.getDatabase(getContext()).timeAllowedDao().getAllTimeAllowed();
AppExecutors.xMain(() -> {
adapter.refreshData(list);
});
});
}
...
答案 0 :(得分:0)
总之,是的。您需要通知适配器您的数据已更改,在这种情况下,查询数据库后该数据正在更改。
此外,作为建议,请尝试研究适配器类的invalidate
和notifyDataSetChanged
。
此外,您可以签出this Answer来了解有关通知适配器数据集更改的更多信息。但是同样,即使我们使用的是Threads(),用于通知的代码也是在UIThread中执行的,它不过是Main线程。
希望这可以解决您的问题。