簡體   English   中英

由於屏幕旋轉,如何處理碎片中的AsyncTask未完成

[英]How do I handle AsyncTask incompletion in fragments due to screen rotation

我有一個App通過Fragment容器(在Tab上)打開幾個片段(實際上是3個),第一個片段使用AsyncTask將feed下載到應用程序中。 屏幕旋轉時會出現問題 - 應用程序崩潰。 我暫時通過將PostExecute中的數據加載到私有靜態變量來處理此問題,但是當用戶首次進入應用程序時仍會出現此問題。

這似乎是一個非常普遍或猖獗的問題,但我在這里找不到徹底的解決方案。 我知道這是因為AsyncTask在與UI線程並行的線程上運行時由於屏幕旋轉導致的配置更改。 我在這個階段沒有使用Java線程/執行器/執行器服務,因為在AsyncTask中似乎有一個現成的工具

我無法中斷該過程以便成功重新啟動活動或片段並丟棄最初的后續AsyncTask調用。

換句話說,當屏幕旋轉等連續配置更改時,如何銷毀片段中的AsyncTask。 非常感謝您的幫助。

public class MolyListFragment extends Fragment {
public final static String MOLY_ARTICLE_DATA = "No Details";
private static final String TAG = "MOLY";
private static ArrayList<MolyPg> mMolyPgs = null;

@Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (mMolyPgs == null) {
        new MolyLoadTask().execute(getResources().getString(R.string.mly_feed));
    }
    else
        displayMlicles (mMolyPgs); //this displays the arrayList out of static mMolyPgs
}


private class MolyLoadTask extends AsyncTask<String, Void, ArrayList<MolyPg>> {
@Override
protected ArrayList<MolyPg> doInBackground(String... urls) {
        String myUrl = urls[0];
        ArrayList<MolyPg> myMlPgs = null;
    try {
            myMlPgs =  loadXmlFromNetwork(myUrl);
    } catch (MalformedURLException e) {
        Log.d(TAG, "MalformedURLException", e);
    } catch (IOException e) {
            getResources().getString(R.string.connection_error);
    } catch (XmlPullParserException e) {
            getResources().getString(R.string.xml_error);
    }

    return myMlPgs;
    }


    @Override
    protected void onPostExecute(ArrayList<MolyPg> result) {
        super.onPostExecute(result);

        Do some acrobatics here
    }
........    
    }
}

您可以使用多種解決方案,但它們都有一個共同的主題......您不應該像這樣直接綁定到用戶界面類的長期運行操作。

如果我提出建議,有兩種可能性很好:

  • 實現你AsyncTask一個自定義的內部AsyncTaskLoader可以連接每個時間Fragment再次啟動檢索數據或等待它回來。 您需要實現許多回調方法,因此您需要參考文檔( 鏈接 )。 您可能還需要查看CursorLoader的源代碼以獲取AsyncTaskLoader實現的另一個示例。
  • 在您的應用程序中創建“數據” Fragment ,其唯一目的是管理您的后台任務並在可用時提供信息。 這個片段沒有UI組件(即不要覆蓋onCreateView() ),你將調用setRetainInstance()因此FragmentManager只保留一個。 當您使用常量標記值添加片段時,UI中的所有其他組件都可以通過FragmentManager輕松找到它以檢索數據。 有關此內容的更多信息,請參閱文檔部分添加不帶UI的片段

如果您正在使用片段,則應使用加載器。 檢查文檔:

http://developer.android.com/reference/android/app/LoaderManager.html

該片段將找到任何先前創建的加載器並“重新連接”,因此您可以從中獲取結果。

有一些方法可以“重新連接”AsyncTasks,但你最好只使用Loaders。

你可以使用setRetainInstance() ,但是正如文檔所說,這只能用於不在后棧中的片段

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM