2016-07-25 86 views
4

我正在閱讀如何在UI和後臺線程here之間進行交互。Android -Retained headless fragment

本文下面的註釋:

的的AsyncTask不會自動處理配置更改, 即如果活動被重建。程序員必須在他的編碼中處理這個 。對此的常見解決方案是在保留的無頭片段中聲明AsyncTask 。

我不明白什麼是保留無頭碎片。

例如,通過這種方式,我可以添加片段:

FragmentManager manager = getSupportFragmentManager(); 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.add(R.id.frame, new MyFragment()); 
transaction.commit(); 

而在片段我可以執行的AsyncTask是這樣的:

MyTask myTask = new MyTask(); 
String[] args = {"Hello"}; 
myTask.execute(args); 

這是所謂的「申報的AsyncTask在保留無頭碎片「?

回答

4

無頭片段不過是一個沒有視圖的片段。在片段lifeCycle的onCreate()中,使用setRetainInstance()true;。即使活動重新創建,這也不會破壞片段。所以如果一個AsyncTask在片段中運行,在活動的重新創建中,你不會失去AsyncTask。

在活動的onCreate中,您必須添加帶有標記的片段。在添加之前,檢查片段是否存在,使用getFragmentManager().findFragmentByTag(TAG),如果片段爲空,則創建片段的新實例並添加它。 在片段中不會有任何膨脹的視圖,因此不需要覆蓋onCreateView()

headlessFragment的例子:

public class HeadlessProgressFragment extends Fragment { 

private ProgressListener mProgressListener; 
private AsyncTask<Void, Integer, Void> mProgressTask; 

public interface ProgressListener { 
    void updateProgress(int progress); 
} 

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

public void setProgressListener(Context context) { 
    mProgressListener = (ProgressListener) context; 
} 

public void startProgress(final int size) { 
    if (mProgressTask == null || mProgressTask.getStatus() != AsyncTask.Status.RUNNING || mProgressTask.getStatus() == AsyncTask.Status.FINISHED) { 
      mProgressTask = new AsyncTask<Void, Integer, Void>() { 
       @Override 
       protected Void doInBackground(Void... params) { 
        for (int index = 0; index < size; index++) { 
         try { 
          Thread.sleep(5000); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } finally { 
          publishProgress(index + 1); 
         } 
        } 
        return null; 
       } 

       @Override 
       protected void onProgressUpdate(Integer... values) { 
        super.onProgressUpdate(values); 
        if (mProgressListener != null) { 
         mProgressListener.updateProgress(values[0]); 
        } 
       } 
      }; 
      mProgressTask.execute(); 
     } 
    } 
} 

在活動事情是這樣的:通過檢查

public class MainActivity extends FragmentActivity implements HeadlessProgressFragment.ProgressListener { 

private static final String TAG = "progress_fragment"; 
private ProgressBar mProgressBar; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.dummy_view); 
    mHeadlessProgressFragment = (HeadlessProgressFragment) getSupportFragmentManager().findFragmentByTag(TAG); 
    if (mHeadlessProgressFragment == null) { 
     mHeadlessProgressFragment = new HeadlessProgressFragment(); 
     getSupportFragmentManager().beginTransaction().add(mHeadlessProgressFragment,TAG).commit(); 
    } 
    mHeadlessProgressFragment.setProgressListener(this); 
    mRectFillingView = (ProgressRectFillingView) findViewById(R.id.progress_bar); 
    final Button startFillBtn = (Button) findViewById(R.id.btn_start_filling); 
    startFillBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      mHeadlessProgressFragment.startProgress(100); 
     } 
    }); 
} 

    @Override 
    public void updateProgress(int progress) { 
     mProgressBar.setProgress(progress); 
    } 
} 
0

正如我在我的情況下,簡化了複雜的只需更新UI(如果有)調用片段或活動是否存在。通過分配調用實體的弱引用來啓動異類。