我有一个应用程序,它从sqlite数据库读取以构建UI。
但是,从sqlite读取是阻塞的,可能会导致ANR。在绘制UI之前运行所需的UI阻止代码的最佳做法是什么?
答案 0 :(得分:3)
使用AsyncTask
https://developer.android.com/reference/android/os/AsyncTask.html
完成处理后,请使用onPostExecute (Result result)
更新您的用户界面。
编辑:
只是详细说明,当您在doInBackground (Params... params)
中实施AsyncTask
时,不要与您的UI线程互动,因为该方法未在UI thread
上执行。
如果您需要更新自己的用户界面,请执行onPreExecute()
,在执行后台任务之前更新,onProgressUpdate (Progress... values)
,在进行更新时后台任务和/或onPostExecute (Result result)
,用于AsyncTask
完成的工作。 "用法"开发人员文档的一部分(来自上面的链接)有一个很好的onProgressUpdate (Progress... values)
编辑2:
处理用户界面
在Indeterminate
正在运行时显示(AsyncTask
)进度条是一种很好的做法。
示例布局XML是:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Use whichever style of progress bar you need, this one is a rotating circle and is indeterminate. Note, it is "gone" by default. The visibility toggle is handled by the AsyncTask -->
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="gone" />
<LinearLayout
android:id="@+id/uiContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- your UI here -->
</LinearLayout>
</RelativeLayout>
在AsyncTask.onPreExecute()
方法中:
protected void onPreExecute()
{
progressBar.setVisibility (View.VISIBLE);
uiContainer.setVisibility (View.INVISIBLE); // optional, up to you if you need to hide your UI
// Do other things here
}
并在AsyncTask.onPostExecute (Result result)
protected void onPostExecute(Result result)
{
progressBar.setVisibility (View.GONE);
uiContainer.setVisibility (View.VISIBLE); // refer to the optional above in onPreExecute
// Do other things here
}
同样,这是一个例子,根据您的需要自定义/使用