Мне трудно понять, как мне следует выполнять фоновую обработку запросов к базе данных Room.Извините, если об этом спрашивают в другом месте, я не могу найти пример с помощью поиска.
У меня есть одновременно более 16 разных таблиц, и пользовательский интерфейс представляет любые важные детали для пользователя через наблюдателей LiveData.
В моем приложении есть контроллеры, которые управляют запросами к базе данных ихранить данные изменяемых объектов в постоянной переменной, которая впоследствии записывается в базу данных для поддержания низкого уровня задач БД.Каждый из этих контроллеров управляется с помощью Executor Service (Executors.newSingleThreadExecutor();)
Команды для контроллеров выполняются через новую отправку, создающую новый пул.Я пытался использовать newCachedThreadPool()
и некоторые другие многопоточные опции, но время отклика в приложении было намного медленнее.Когда-то внутри контроллера есть еще один вызов newSingleThreadExecutor()
, которым управляет каждый контроллер.
Мое время отклика довольно хорошее - но мой пользовательский интерфейс не обновляется, когда я хочу это с наблюдателями.Я чувствовал, что раньше в моей разработке, когда у меня было намного меньше ExecutorServices, он работал чрезвычайно медленно, но интерфейс обновлялся так, как я хотел.У меня очень отчетливое впечатление, что, хотя мой код работает, это просто не то, как я должен это делать.Иногда в моем отладчике у меня будет около 30 + пулов, каждый с одним потоком.Пожалуйста, посоветуйте.
Когда у меня цикл for () выполняет кучу событий addHour подряд, в идеале каждый HomeScreen.addHour(x)
должен выстраиваться в очередь для последовательного выполнения.Я не уверен, что это происходит сейчас - кто-нибудь может уточнить это для меня?Я очень новичок в этом, и многопоточность оказывается сложной - большое спасибо.
public class HomeScreen extends AppCompatActivity implements LifecycleOwner {
CitiesController citiesController;
ExecutorService executorService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maincontainer);
executorService = Executors.newSingleThreadExecutor();
citiesController = ViewModelProviders.of(this).get(CitiesController.class);
citiesController.getLiveCities().observe(this, cities -> {
//UpdateUI
});
}
public void addHour(int hours){
if(executorService.submit(() -> {
citiesController.addHour(hours);
}).isDone()){
citiesController.saveAll(); //the act of writing databases should update observer?
}
}
}
public class CitiesController extends AndroidViewModel {
//cellControllers functions much like citiesController and has a unique executorService.
public ArrayList<CellsController> cellControllers;
public List<LivingCity> cities;
private CityDao cityDao;
private ExecutorService executorService;
public CitiesController(@NonNull Application application){
super(application);
Log.v("CitiesCtrl","Starting a new controller.");
// executorService = Executors.newCachedThreadPool();
executorService = Executors.newSingleThreadExecutor();
cityDao = CityDB.getInstance(application.getApplicationContext()).cityDao();
cities = new ArrayList<>();
executorService.execute(this::setCities);
}
public void addHour(int hours){
executorService.execute(() -> {
for(CellsController cellsController : cellControllers){
cellsController.addHour(hours);
}
});
}
private void setCities(){
//fills List<LivingCity>cities with entries from DB successfully
//Also fills List<CellsController>cellControllers with entries from DB successfully.
}
public LiveData<List<LivingCity>> getLiveCities(){
return cityDao.findAllLive();
}
private void saveAll() {
cityDao.updateAll(cities);
}
}