线程中的异步回调

时间:2018-07-31 19:20:59

标签: java android multithreading

我学习Android并有小问题。也许我能够处理,但是我想知道解决此类问题的最佳解决方案。

目的是使API调用外部服务(使用Volley),并将结果保存到数据库(使用Room)。

我已经开始模拟API结果并将其保存到数据库。按照良好的做法,我使用单独的线程来做到这一点。后来我通过RequestQueue添加了发出API请求的功能,现在我有了类似的东西:

// 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函数中,我再次进入UI线程,因此无法在数据库上使用操作。我应该在那里创建新线程吗?如果是这样,我将必须将响应变量传递到此线程中,所以我认为这不是一个好主意。还有哪些其他选择,哪个是最好的?这是我的问题。

2 个答案:

答案 0 :(得分:1)

这似乎是创建凌空custom request的不错选择。

您可以创建一个扩展Request的类,并在parseNetworkResponse中执行所需的任何后台操作(例如保存到数据库),因为这是从辅助线程调用的。然后,当请求完成时,由于该回调是在主线程上进行的,因此您可以在liverResponse中执行任何后续的UI线程操作。

答案 1 :(得分:0)

除了在这里创建新线程外,别无其他方法,否则您必须能够在除主线程之外的其他线程上接收网络结果(具有改装功能的Rx-java可以在此处帮助您),或者您可以使用{ {3}}如果要遵循当前代码,只需使用RxVolley将数据传递到异步任务并在doInBackground()中进行数据库事务