Android AsyncTask在线程完成之前不调用onPreExecute
我有一个片段,它有一个列表,对于这个列表,我希望在加载列表时显示一个加载图标,然后再显示列表。这是我的列表片段布局,通过调用Android AsyncTask在线程完成之前不调用onPreExecute,android,multithreading,listview,concurrency,android-asynctask,Android,Multithreading,Listview,Concurrency,Android Asynctask,我有一个片段,它有一个列表,对于这个列表,我希望在加载列表时显示一个加载图标,然后再显示列表。这是我的列表片段布局,通过调用View rootView=inflater.inflate(R.layout.main\u list\u card,container,false)进行充气位于片段的onCreateView()中 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too
View rootView=inflater.inflate(R.layout.main\u list\u card,container,false)进行充气代码>位于片段的onCreateView()中
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity$DummySectionFragment"
android:layout_gravity="center">
<ListView
android:id="@+id/mainList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="6dp"
android:listSelector="@android:color/transparent"
android:visibility="invisible"/>
<ProgressBar
android:id="@+id/loadingIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
问题是一旦调用它,UI线程就完全冻结,甚至还没有更改视图,然后一旦加载,我会看到加载图标闪烁,然后显示列表并显示加载图标。我不确定我的片段中的onCreateView是在之后调用的还是其他什么,但我正试图让它在片段以显示列表加载的方式创建时被正确调用。InstalledAppsLoader类如下所示:
public class InstalledAppsLoader extends AsyncTask<Void, Void, List<App>>{
private ProgressBar bar;
private ListView list;
public InstalledAppsLoader(ProgressBar bar, ListView list)
{
this.bar = bar;
this.list = list;
}
@Override
protected void onPreExecute() {
bar.setVisibility(View.VISIBLE);
list.setVisibility(View.INVISIBLE);
super.onPreExecute();
}
@Override
protected List<App> doInBackground(Void... params) {
return MainFragment.getInstalledApps();
}
@Override
protected void onPostExecute(List<App> result) {
bar.setVisibility(View.INVISIBLE);
list.setVisibility(View.VISIBLE);
super.onPostExecute(result);
}
}
公共类InstalledAppsLoader扩展异步任务{
私人酒吧;
私有列表视图列表;
公共安装的AppsLoader(进度条、列表视图列表)
{
这个.bar=bar;
this.list=列表;
}
@凌驾
受保护的void onPreExecute(){
bar.setVisibility(View.VISIBLE);
list.setVisibility(View.INVISIBLE);
super.onPreExecute();
}
@凌驾
受保护列表doInBackground(无效…参数){
返回MainFragment.getInstalledApps();
}
@凌驾
受保护的void onPostExecute(列表结果){
设置可见性(视图不可见);
list.setVisibility(View.VISIBLE);
super.onPostExecute(结果);
}
}
由于并发编程对我来说是一个相对较新的概念,所以我已经在这方面停留了一段时间,所以非常感谢您的帮助 因此
try {
apps = loader.get();
}
AsyncTask的As.get()
方法是UI线程阻塞方法。它不会异步运行您的异步任务
您还调用了两次AsyncTask
loader.execute(); // 1
try {
apps = loader.get(); // 2 time
}
删除apps=loader.get()代码>从UI线程,使用异步任务的onPostExecute()
中的apps
成员
编辑:
@Override
protected void onPostExecute(List<App> result) {
apps = result; // Use apps here
bar.setVisibility(View.INVISIBLE);
list.setVisibility(View.VISIBLE);
super.onPostExecute(result);
}
@覆盖
受保护的void onPostExecute(列表结果){
apps=result;//在此处使用应用程序
设置可见性(视图不可见);
list.setVisibility(View.VISIBLE);
super.onPostExecute(结果);
}
@AggieDevloader.execute()
是否足够在本例中,我是否通过引用传入“apps”,以便设置值并在主线程中接收它?在我的程序中,它是一个单独的类,不继承应用程序。是的,可以传递应用程序的引用
,也可以将其用作静态
成员字段。我会避免在类名中使用“Loader”,因为它表明它是一个加载器。考虑重命名它来安装AppStask。
@Override
protected void onPostExecute(List<App> result) {
apps = result; // Use apps here
bar.setVisibility(View.INVISIBLE);
list.setVisibility(View.VISIBLE);
super.onPostExecute(result);
}