我有一个应用程序,从一个sqlite数据库读取,以建立UI。
然而,从sqlite读取是阻塞的,可能会导致ANR。在绘制UI之前运行UI阻塞代码的最佳实践是什么?
使用AsyncTask
https://developer.android.com/reference/android/os/AsyncTask.html
当你完成了你的处理,使用onPostExecute (Result result)
来更新你的UI。
只是为了详细说明,当你在AsyncTask
中实现doInBackground (Params... params)
时,不要与你的UI线程交互,因为该方法不会在UI thread
上执行。
如果你需要更新你的UI,实现onPreExecute()
,用于在执行后台任务之前更新, onProgressUpdate (Progress... values)
,用于在执行后台任务时更新,和/或onPostExecute (Result result)
,用于当你的AsyncTask
完成的工作时。开发人员文档的"用法"部分(来自上面的链接)有一个关于onProgressUpdate (Progress... values)
在AsyncTask
运行时显示(Indeterminate
)进度条是很好的做法。
一个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
}
再一次,这是一个例子,自定义/使用你认为合适的