Android 后台任务中的数据源操作期间ProgressBar未旋转
我正在尝试将一些数据加载到布局中。我通过Android 后台任务中的数据源操作期间ProgressBar未旋转,android,android-asynctask,android-progressbar,Android,Android Asynctask,Android Progressbar,我正在尝试将一些数据加载到布局中。我通过异步任务加载数据,该任务将从SQLite数据源加载数据,然后在完成时将该数据插入布局。我希望在此期间显示一个进度条,在任务开始时将其添加到布局中,在任务完成时将其从布局中删除 这里有一个大致的轮廓: private class ItemLoader extends AsyncTask<Void, Void, List<Item>> { private Context context; private LayoutI
异步任务
加载数据,该任务将从SQLite数据源加载数据,然后在完成时将该数据插入布局。我希望在此期间显示一个进度条,在任务开始时将其添加到布局中,在任务完成时将其从布局中删除
这里有一个大致的轮廓:
private class ItemLoader extends AsyncTask<Void, Void, List<Item>> {
private Context context;
private LayoutInflater inflater;
private View loading;
public DataLoader(Context context) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.loading = createLoading();
}
private View createLoading() {
return inflater.inflate(R.layout.loading, null);
}
@Override
public void onPreExecute() {
// Insert 'loading' view into the 'items' layout.
LinearLayout layout = (LinearLayout) findViewById(R.id.items);
layout.addView(loading);
}
@Override
protected List<Item> doInBackground(Void... params) {
return loadItemsFromDataSource();
}
private List<Item> loadItemsFromDataSource() {
ItemsSource d = new ItemsDataSource(context);
d.open();
try {
return d.lookupItems();
} finally {
d.close();
}
}
@Override
public void onPostExecute(List<Item> items) {
LinearLayout layout = (LinearLayout) findViewById(R.id.items);
// Remove 'loading' view from the 'items' layout.
layout.removeView(loading);
// Add items to the 'items' layout.
for (Item item: items) {
addItemToLayout(item, layout);
}
}
我可以看到,在后台加载数据时,“加载”微调器和文本被添加到我的布局中,而在将数据添加到布局中时,此微调器/文本被删除
但是当doInBackground()
方法运行时,微调器没有旋转。我正在UI线程中添加和删除进度条(在onPreExecute()
和onPostExecute()
方法中)
有趣的是,如果在从数据源加载数据之前在doInBackground()
中添加一个sleep()
调用,那么我可以看到微调器正在旋转。但一旦进行了数据源调用,微调器就会停止旋转:
@Override
protected void doInBackground(Void... params) {
sleepForFiveSeconds(); // spinner is spinning
List<Item> items = loadItemsFromDataSource(); // spinner stops spinning
sleepForFiveSeconds(); // spinner still not spinning
return items;
}
@覆盖
受保护的void doInBackground(void…参数){
sleepForFiveSeconds();//微调器正在旋转
List items=loadItemsFromDataSource();//微调器停止旋转
sleepForFiveSeconds();//微调器仍不旋转
退货项目;
}
而且它不仅仅是在异步任务
中操纵的微调器。我注意到将ProgressBar添加到活动时的相同行为,方法是在活动的布局中定义它,或者在活动的onCreate()
方法中动态添加它。在这些情况下,微调器一直旋转,直到执行数据源查找为止。一旦数据源查找返回,它将再次开始旋转
因此,看起来微调器是在UI线程中访问的,但是后台线程中的数据源操作导致这些微调器停止
有什么建议吗
编辑添加:这适用于我的Nexus 7(Android 4.2)和HTC phone(Android 2.3.4),Android清单将最低SDK版本设置为10。不要从布局中添加和删除微调器,尝试将其包含在基本
itemsLayout
文件中,只需切换可见性即可。因此,类似于findviewbyd(R.id.load).setVisibility(View.VISIBLE)代码>。这应该比膨胀一个全新的布局所需的时间要少,这正是您现在正在做的。谢谢您的回复。我将加载布局直接添加到活动的布局中,并将加载布局设置为在onPreExecute
期间可见,在onpostexecute
期间消失。微调器正确显示和消失,但在数据源操作期间仍不旋转。后台任务需要多长时间?你试过计时了吗?有可能只是完成得太快,旋转器无法有效启动。您还可以尝试将微调器上的android:undeterminate
属性设置为true
。数据加载的范围从几乎瞬间到几秒钟不等。请注意,在数据加载完成后,我还将sleep()
调用放入后台任务的doInBackground()
方法中,但微调器仍然没有旋转。我将尝试显式地将android:indermite
设置为true
,但根据文档,默认情况下微调器是不确定的。数据加载代码打开数据源,调用数据源上的SQL操作,然后关闭数据源。我用Thread.sleep(2000)
替换了SQL操作,微调器工作正常。因此,实际SQLite调用/游标到对象转换中的某些内容导致了问题。我在ListView
中使用了一个ArrayAdapter
,它显示了从数据存储中获取的项。因此,数据存储执行SQL查询,然后在光标上迭代以构造对象数组。正是这个操作(或者至少是第一个这样的操作,如果将查询分解为块的话)破坏了处理器周期并停止了进度条微调器动画。我将尝试使用CursorAdapter
而不是ArrayAdapter
并查看是否有任何改进。ItemsDataSource
和lookupItems
的源代码是什么?您的活动是否正在进行其他数据库查找?
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.itemsLayout);
...
new ItemLoader(this).execute();
}
@Override
protected void doInBackground(Void... params) {
sleepForFiveSeconds(); // spinner is spinning
List<Item> items = loadItemsFromDataSource(); // spinner stops spinning
sleepForFiveSeconds(); // spinner still not spinning
return items;
}