Я изучаю Android и у меня небольшая проблема. Возможно, я смогу с этим справиться, но я хотел бы знать лучшее решение для такого рода проблем.
Цель состоит в том, чтобы вызвать API-интерфейс внешней службы (с помощью Volley) и сохранить результат в базе данных (с помощью Room).
Я начал с макета результата API и сохранил его в базе данных. Следуя хорошей практике, я использовал для этого отдельный поток. Позже я добавил запрос API с помощью RequestQueue, и теперь у меня есть что-то вроде этого:
// HomeActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
importData();
}
private void importData() {
Thread importData = new Thread(new ImportData());
importData.start();
importData.join();
}
.
// ImportData.java
public class ImportData implements Runnable {
@Override
public void run() {
String url = "http://api.com";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
String data = response.toString();
List<Data> toAdd = new ArrayList<>();
// ... formating data ...
App.get().getDB().dataDao().insertAll(toAdd);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
App.INSTANCE.getRequestQueue().add(jsonObjectRequest);
}
Проблема в том, что после вызова в функции onResponse я снова в потоке пользовательского интерфейса, поэтому я не могу использовать операции с базой данных. Должен ли я создать там новую ветку? Если так, мне пришлось бы передать переменную ответа в этот поток, поэтому я не думаю, что это хорошая идея. Какие еще варианты и какой лучший? Это моя проблема.




Нет другого способа, кроме создания здесь нового потока, иначе вы должны иметь возможность получать сетевой результат в потоке, отличном от основного потока (Rx-java с модификацией может помочь вам там), или вы можете использовать RxVolley, если хотите чтобы следовать текущему коду, просто используйте AsyncTask, передайте данные в асинхронную задачу и сделайте транзакции базы данных в doInBackground ()
Кажется, это хороший кандидат для создания Volley индивидуальный запрос.
Вы можете создать класс, который расширяет Request и делать любые фоновые вещи, которые вы хотите (например, сохранение в вашу базу данных) в parseNetworkResponse, поскольку он вызывается из рабочего потока. Затем, когда запрос завершен, вы можете выполнять любые последующие действия потока пользовательского интерфейса в deliveryResponse, поскольку этот обратный вызов выполняется в основном потоке.
Или вы получаете асинхронный результат внутри onResponse (без потока), или вы вызываете операцию синхронизации внутри своего потока, но второй способ имеет тот же эффект, что и выполнение только в одном потоке