1

我有一個片段有一個列表,並且對於這個列表,我希望加載列表時出現加載圖標,以及之後出現的列表。這是我通過在片段的onCreateView()中調用View rootView = inflater.inflate(R.layout.main_list_card, container, false);來誇大的列表片段佈局。AsyncTask不會調用onPreExecute,直到線程完成

<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); 
    } 


} 

我一直停留在這一段時間,因爲現在併發編程是一個相對較新的想法給我,所以任何幫助,將不勝感激!

+0

我會避免使用「裝載機」在你的類名,因爲它表明,這是一個裝載機。考慮將其重命名爲InstalledAppsTask。 –

回答

3

正因爲如此,

try { 
    apps = loader.get(); 
} 

作爲的AsyncTask的.get()方法是UI線程阻塞方法。它不會異步運行你的AsyncTask。

另外你還打了兩次AsyncTask。

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

從UI線程中移除apps = loader.get();,並在您的AsyncTask的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); 
} 
+0

@AggieDev'loader.execute()'就夠了 – Raghunandan

+0

所以在這個例子中,我是通過引用傳入「apps」,以便我可以設置值並在主線程中接收它?在我的程序中,它是一個單獨的類,不會繼承應用程序。 – AggieDev

+0

是的,要麼傳遞'apps'的引用,要麼可以將其用作'static'成員字段。 – user370305

相關問題