android - 配置更改后或启动这些操作的 Activity 被破坏后,SQLite CRUD 操作的预期行为是什么?

标签 android multithreading sqlite android-contentprovider android-background

我正在重构我不久前制作的一个应用程序。当时我刚刚迈入 Android,最简单的方法就是避免方向更改,对于几乎所有的 CRUD 操作,我都使用 AsyncTask类,没有实现内容提供程序或使用 fragment 。

现在我做了一些改变:

  • 我使用Fragment s 封装功能
  • 对我的数据库的所有访问都是通过 Content Provider 完成的
  • 我使用CursorLoader利用内容观察和自动后台加载 LoaderFramework 来检索我的数据带来。

我现在遇到的唯一问题是我不太确定如何处理其余的 CRUD 操作(创建、更新和删除)。 我发现我可以使用 AsyncQueryHandler类(class),但网上没有足够的信息。 我喜欢 Loader Framework 的一件事是它了解 Activity 或 Fragment 生命周期,但是 AsyncQueryHandler 呢? ?

  • startDelete 启动的操作会发生什么情况, startInsert , startUpdateActivity/Fragment进行配置更改?或者当我按下后退按钮时?或者更糟糕的是,如果 Activity 被破坏了?
  • 在这种情况下,此类操作的预期行为是什么?他们应该被取消还是应该继续做他们的工作?

我上面提到的所有操作都没有那么复杂。对于真正复杂的操作,我使用了 ServiceIntentService s,但由于我不认为在主线程上运行 SQLite 操作是一个好主意,所以我想使用更好的解决方案,但首先我需要知道该解决方案应如何对 Activity 使用react/Fragment生命周期事件。

如有任何意见或建议,我将不胜感激。 谢谢。

最佳答案

如果您使用AsyncQueryHandler,您必须考虑到此抽象包装器是在其启动的线程上创建并执行提供程序操作的。如果您从 UI 线程调用此回调,回调将被发送到 UI 线程。如果您从另一个工作线程调用它,回调将被发送到该工作线程。

这与 fragment 或 Activity 的生命周期无关,ContentProvider 没有生命周期。

AsyncQueryHandler 在基本级别上创建一个 Message 对象,该对象被添加到单个后台线程的 MessageQueue 中。无论您在哪个 Activity/fragment 中使用 AsyncQueryHandler,所有 Message 对象最终都会位于同一个 MessageQueue 上。 一旦后台线程处理了请求,它就会将响应发送回最初发出请求的 AsyncQueryHandler 实例。

我的建议是使用 Android 中的加载器。这些与 Activity/fragment 的生命周期直接相关。您可以在一个 LoaderManager 中拥有多个 Loader(每个 Activity/fragment 一个 LoaderManager),这允许执行更复杂的操作。当内容发生更改时,您的 Activity/fragment 将自动收到通知(当您想要将其与 CRUD 操作的自定义方法结合使用或需要使用长时间运行的服务时非常有用)。他们的另一个非常重要的功能是他们总是会重新连接到最后一个加载器,因此您将避免重新查询您的内容。

我建议您搜索一些在 Android 中实现 Loader 的教程。您可以从这些开始:

回答您最后的评论:

我建议使用 EventBus 库 ( https://github.com/greenrobot/EventBus ) 在 AsyncTasks/Thread 和其他组件之间进行通信。 您可以首先创建一个抽象的 AsyncTask/Thread,然后在其之上创建特定的命令。 例如:

public abstract class AbstractThread extends Thread {

    @Override
    public void run() {
        super.run();

        command();
    }

    abstract void command();
}

在抽象类中,您可以进行一些数据库初始化、验证或任何其他可能对您的应用程序有意义的操作。

public class InserTask extends AbstractThread{

    @Override
    void command() {
        //TODO: Add logic for the insert task
    }
}

public class UpdateTask extends AbstractThread{

    @Override
    void command() {
        //TODO: Add logic for the update task
    }
}

在这些特定的类中,只需添加 CRUD 操作的逻辑即可。

要控制这些线程,例如何时应停止、暂停、恢复它们,您可以创建控制线程的 ThreadPool 管理器。您可以在此处了解如何实现此目的的更多信息:Thread Pool

关于android - 配置更改后或启动这些操作的 Activity 被破坏后,SQLite CRUD 操作的预期行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30969590/

相关文章:

java - 在谷歌地图的 map 版本2中获取 map 中心

android - 如何设置 RelativeLayout 中 LinearLayout 的宽度与屏幕分辨率无关?

c# - 如何在 lambda 表达式中传递 ref 参数? - 线程问题

python - 更新传递给线程python的变量

java - 多次调用 Button 的 OnClickListener

java - 仅从 java 代码创建 fragment

multithreading - 为什么本地创建的结构不能发送到另一个线程?

python sqlite - 数据库加载到内存(RAM)?

.net - SQLite,将平台特定的 dll 复制到 bin 文件夹

mysql - 在 Django 中将 SQLite3 数据库迁移到 MySQL