在线程完成之前,AsyncTask不会调用onPreExecute

时间:2014-03-03 06:30:55

标签: android multithreading listview concurrency android-asynctask

我有一个包含列表的片段,对于此列表,我希望在加载列表时显示加载图标,然后显示列表。这是我的列表片段布局,通过在片段的onCreateView()中调用View rootView = inflater.inflate(R.layout.main_list_card, container, false);来膨胀。

<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>

我的想法是我调用list.setVisibility(View.INVISIBLE);和bar.setVisibility(View.VISIBLE);列表正在加载,而加载后则相反。我的asynctask以下面的方式调用(在片段的onResume()中调用):

InstalledAppsLoader loader = new InstalledAppsLoader(bar, list);
loader.execute();
try {
    apps = loader.get();
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (ExecutionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

问题是一旦调用它,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);
    }


}

我已经坚持了一段时间,因为并发编程对我来说是一个相对较新的想法,所以任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:3)

因此,

try {
    apps = loader.get();
}

AsyncTask的.get()方法是UI线程阻塞方法。它不会异步运行AsyncTask。

你也是两次调用AsyncTask。

loader.execute(); // 1 
try {
    apps = loader.get(); // 2 time
}

从UI线程中删除apps = loader.get();并使用AsyncTask的apps中的onPostExecute()成员。

修改

@Override
protected void onPostExecute(List<App> result) {
    apps = result; // Use apps here
    bar.setVisibility(View.INVISIBLE);
    list.setVisibility(View.VISIBLE);
    super.onPostExecute(result);
}