2012-05-09 57 views
1

從onCreate中的initLoader總是需要在片段中嗎?如果加載器的關鍵參數依賴於另一個加載器的結果呢?延遲加載程序

即你有2個裝載機:LoaderA和LoaderB。 LoaderB需要LoaderA運行的結果。 LoaderA和LoaderB都在片段的onCreate中初始化,但LoaderB沒有被賦予任何參數,故意故障失敗。 一旦LoaderA完成,LoaderB將以新的參數重新啓動,以便它可以執行其所需的請求。

裝載機初始化的片段:

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    getLoaderManager().initLoader(LOADER_A, new Bundle(), this); 
    getLoaderManager().initLoader(LOADER_B, null, mLoaderBCallback); 
} 

爲LOADER_A回調的片段:mLoaderBCallback的片段

@Override 
public Loader<MyResultObject> onCreateLoader(int id, Bundle args) { 
    return new LoaderA(getActivity(), args); 
} 

@Override 
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) { 
    if (result != null) { 
     Bundle args = new Bundle(); 
     args.putInt("id", result.getId()); 

     getLoaderManager().restartLoader(LOADER_B, args, mLoaderBCallback); 
    } 
} 

定義:

private LoaderBCallback mLoaderBCallback = new LoaderBCallback(); 

(LoaderBCallback的執行不重要的是,它只是標準的LoaderCallbacks接口。阿泰LoaderB的一個實例,當裝載完成後處理)

LoaderB類(請原諒任何潛在的編譯器錯誤這個類的定義,它只是一個例子):

public class LoaderB<List<AnotherResultObject>> extends AsyncTaskLoader<List<AnotherResultObject>> { 
    private Bundle mArgs; 

    public LoaderB(Context context, Bundle args) { 
     super(context); 
     mArgs = args; 
    } 

    @Override 
    public List<AnotherResultObject> loadInBackground() { 
     if (mArgs == null) { 
      // bail out, no arguments. 
      return null; 
     } 


     // do network request with mArgs here 
     return MyStaticClass.performAwesomeNetworkRequest(mArgs); 
    } 

    // boiler plate AsyncTaskLoader stuff here 
    ...... 

} 

有沒有更好的辦法?我們可以不使用LoaderB的initLoader嗎?

編輯:我的印象是,裝載機總是必須在onCreate中初始化,以便他們可以處理配置更改。這隻適用於活動中的裝載者。在Fragments中創建的加載器無論在什麼地方初始化,都能得到管理?

回答

1

您可以在代碼的任何位置初始化加載程序。

在你的情況下,你應該用initLoader替換你的restartLoader onLoadFinished。另外,你應該檢查onLoadFinished中加載器的ID,以便知道哪個加載器完成了。

編輯:您正在使用一個單獨的偵聽器LOADER_B回調,所以我的ID檢查點有點被打敗那裏..但無論如何..你可以將它們合併成一個,如果你想

@Override 
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) { 
    switch (loader.getId()) 
    { 
     case LOADER_A: 
     if (result != null) { 
      Bundle args = new Bundle(); 
      args.putInt("id", result.getId()); 
      // i put "this" as the callback listener. you can use your custom one here if you want 
      getLoaderManager().initLoader(LOADER_B, args, this); 
     } 
     break; 
     case LOADER_B: 
     //do whatever 
     break; 
} 
+0

任何想法如果加載程序仍然能夠在生命週期事件(如方向更改)中生存下來,如果您不將它們初始化爲重要的地方? – NPike

+0

它應該。加載器結果將通過方向更改持久化。 – dymmeh