在 onCreate() 期间通过 AsyncTask 加载数据

Posted

技术标签:

【中文标题】在 onCreate() 期间通过 AsyncTask 加载数据【英文标题】:Loading data during onCreate() via AsyncTask 【发布时间】:2019-01-25 21:36:20 【问题描述】:

我试图在onCreate 期间通过 AsyncTask 从Room 数据库加载数据(也在onStart 期间尝试过)。问题是,我通过WeakReference 将上下文传递给AsyncTask,有时(四分之一)上下文在onPostExecute 上变为空,即使任务几乎立即完成(这是一个小型数据库)。

我不知道哪种方法是通过 AsyncTaskonCreate 方法上加载数据的正确方法,而不会冒着上下文很快变为 null 的风险 - 我知道必须通过 WeakReference 来完成以避免内存泄漏,但我认为由于某种原因,活动有时会很快重新创建,以至于任务无法将结果发布到原始上下文,并且数据不会显示在 Activity 中。

考虑到任务几乎立即完成,但Room 库需要通过另一个线程来完成它(也提高了性能和响应能力),任何想法是什么是正确的处理方法?

所以为了清楚起见,我试图以这种方式访问​​上下文:

public MyTask(ActivityListener listener) 
    mWeakContext = new WeakReference(listener);


protected void onPostExecute(Boolean result) 
    AcitivtyListener aListener = mWeakContext.get();
    if (aListener != null) aListener.refresh(data);

ActivityListener 接口在调用new MyTask(new ActivityListener() ... ); 时匿名实现

谢谢

【问题讨论】:

【参考方案1】:

是的,我认为 context 变为 null 意味着重新创建了活动,但它似乎不太可能发生,因为我想象它如此之快,以至于你无法比数据库操作更快地旋转手机

这个问题的间接答案就是:根本不要使用AsyncTask,使用ViewModelLiveData——它们是谷歌架构的一部分,也是你正在使用的Room的一部分

简而言之,这两个组件将解决生命周期管理/上下文泄漏的问题,并将结果发送到正确的 Activity 实例

查看关于 LiveData 和 ViewModel 的文档:livedataviewmodel

【讨论】:

感谢您的回答。我将检查这是否解决了问题(这不是微不足道的)并考虑明天验证答案!干杯 是的,这不是微不足道的,但如果你投入时间,我想你会发现这种方法更好,也许如果你研究一下让我们说 RxJava,你将完全离开 AsyncTasks,喜欢听听你的进展

以上是关于在 onCreate() 期间通过 AsyncTask 加载数据的主要内容,如果未能解决你的问题,请参考以下文章

为啥活动通过 onCreate 而不是 onRestart 回到前面?

安卓应用如何在整个应用运行期间都禁止弹出输入法面板?

创建 Activity 对象时是不是调用 onCreate?

使用 onCreate 与 onRestoreInstanceState

super.onCreate(savedInstanceState);

如何在onCreate方法中获取视图的宽度和高度