android - Fragments 中的 AsyncTask 执行数据库更新

标签 android multithreading android-fragments android-asynctask

我有超过 10 个 fragment ,它们执行相同类型的任务:

  1. 使用 Retrofit 从服务器检索数据
  2. 启动异步任务来更新数据库(使用 ORMLite)
  3. 数据库更新后,从数据库中检索新数据
  4. 通知适配器中的数据集已更改

我想知道,一旦我从服务器检索数据,将更新数据库代码放入我的 fragment 中的 AsyncTask 中是否没有用? 我很难理解什么在 UI 线程上运行,什么不运行,应该通过 AsyncTask

作为他自己的线程启动

这是我的代码:

private void getLocalIncidentTemplate() {
    mIncidentTemplate.clear();
    mIncidentTemplate.addAll(GenericDAO.getInstance(EntityGroup.class).queryForAll());
    Collections.sort(mIncidentTemplate);
    Log.e(TAG, "Incident Template count:" + mIncidentTemplate.size());
    mListAdapter.notifyDataSetChanged();
    spinner.setVisibility(View.GONE);
}

private void getRemoteIncidentTemplate() {
    Call<EntityIncident> call = meepServices.getIncidentTemplate();
    call.enqueue(new Callback<EntityIncident>() {
        @Override
        public void onResponse(Call<EntityIncident> call, Response<EntityIncident> response) {
            if (response.isSuccessful()) {
                new updateIncidentTemplateTask().execute(response.body());
            }
        }

        @Override
        public void onFailure(Call<EntityIncident> call, Throwable t) {
            t.getStackTrace();
            Log.e(TAG, t.toString());
            Utils.showToastMessage(getActivity(), "Error retrieving Incidents", true);
        }

    });
}

private class updateIncidentTemplateTask extends AsyncTask<EntityCategories, Void, Boolean> {

    @Override
    protected Boolean doInBackground(EntityCategories... params) {
        updateIncidents(params[0]);
        return true;
    }

    protected void onPostExecute(Boolean b) {
        getLocalIncidentTemplate();
        spinner.setVisibility(View.GONE);
    }
}

这是使用 ORMlite 进行的数据库更新:

private void updateIncident(EntityCategories categories) {

    try {
        categories.setId("MobilePlan");
        //Update base categories
        GenericDAO.getInstance(EntityCategories.class).addOrUpdate(categories);

        for (EntityCategories.EntityCategory currentCategory : new ArrayList<>(categories.getCategories())) {

            if (currentCategory.getmPlans() != null) {
                for (EntityPlan myPlan : new ArrayList<>(currentCategory.getmPlans())) {
                    EntityPlan oldPlan = GenericDAO.getInstance(EntityPlan.class).queryById(String.valueOf(myPlan.getmId()));
                    myPlan.setCategories(currentCategory);
                    if (oldPlan != null) {
                        if (!myPlan.getmDateModification().equals(oldPlan.getmDateModification())) {
                            GenericDAO.getInstance(EntityPlan.class).addOrUpdate(myPlan);
                        }
                    } else {
                        GenericDAO.getInstance(EntityPlan.class).addOrUpdate(myPlan);
                    }
                }

            } else {
                continue;
            }

            GenericDAO.getInstance(EntityLabel.class).addOrUpdate(currentCategory.getmLabel());
            currentCategory.setCategories(categories);
            GenericDAO.getInstance(EntityCategories.EntityCategory.class).addOrUpdate(currentCategory);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    Log.d(TAG, "DATA updated");
}

最佳答案

对于您的特定情况,您应该使用 AsyncTask 从后端检索数据并将其放入数据库中。 请记住,AsyncTask 具有三个主要方法:

  • onPreExecute() 在 UI 线程上运行。当您需要准备需要 UI 线程的内容(触摸 View 等)时很有用
  • doInBackGround() 这在后台线程上运行
  • onPostExecute() 也在 UI 线程上运行。

onPostExecute()中,您可以向适配器通知新数据。

如果我是你,我会使用加载器来获取通知并从数据库中检索数据。这样完整的链条将是一些:

  1. AsyncTask从后端拉取数据并存储到数据库
  2. 您的加载程序将收到数据库内部发生更改的通知,并从中提取数据并调用 Activity/fragment 内的 onLoadFinished() 方法
  3. onLoadFinished() 将数据传递到 View 适配器。

我还没有详细说明如何实现这一点。我刚刚介绍了总体架构。

关于android - Fragments 中的 AsyncTask 执行数据库更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36698530/

相关文章:

c# - 为什么 Parallel.Foreach 会创建无限线程?

c# - 如何在 C# 中保持线程存活

android - 使用许多 fragment 是一种不好的做法吗?

java - fragment 替换不起作用

Android Kotlin 从 Activity 中获取 Fragment 中的 Zxing 条码结果

java - android: 找不到符号 TaskDescription

android - 构建在调试中工作,在发布中失败 - ZipException 重复条目

java - 我需要将 JsonObject 转换为 HashMap ,但 JSON 的结构有点不同

android - 如何在Android应用程序中使用Oracle存储过程

python - 调用嵌入式Python模块时,是否切换了线程?