2016-07-25 18 views
4

Ich lese darüber, wie here zwischen UI und Hintergrund-Thread zu interagieren.Android -Retained kopflos Fragment

Dieser Artikel folgende Anmerkung hat:

Die AsyncTask keine Konfigurationsänderungen automatisch handhaben, das heißt, wenn die Aktivität neu erstellt wird. Der Programmierer muss das in seiner Codierung behandeln. Eine gängige Lösung hierfür ist, die AsyncTask in einem beibehaltenen kopflosen Fragment zu deklarieren.

Ich verstehe nicht, was kopfloses Fragment beibehalten wird.

Zum Beispiel auf diese Weise kann ich hinzufügen Fragment:

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

Und Fragment kann ich AsyncTask wie folgt auszuführen:

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

Ist das „genannt AsyncTask in einem beibehalten zu erklären kopfloses Fragment "?

Antwort

4

Headless Fragment ist nichts anderes als ein Fragment, das keine Aussicht hat. Verwenden Sie in onCreate() des Fragments lifeCycle setRetainInstance()true;. Dies wird das Fragment nicht zerstören, selbst wenn die Aktivität neu erstellt wird. Wenn also eine AsyncTask in einem Fragment ausgeführt wird, verlieren Sie beim Wiederherstellen der Aktivität nicht die AsyncTask.

In onCreate der Tätigkeit, haben Sie das Fragment mit einem Tag hinzuzufügen. Überprüfen Sie vor dem Hinzufügen, ob das Fragment unter Verwendung von getFragmentManager().findFragmentByTag(TAG) existiert. Wenn das Fragment null ist, erstellen Sie eine neue Instanz des Fragments und fügen Sie es hinzu. In Fragmente wird es keine Aussicht aufgeblasen sein, so dass keine Notwendigkeit onCreateView() außer Kraft zu setzen.

Ein Beispiel für 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(); 
     } 
    } 
} 

In Aktivität Etwas wie folgt aus:

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

Wie ich die Komplexität in meinem Fall aktualisieren vereinfacht, indem Sie Ihre UI (wenn Sie müssen), indem geprüft das anrufende Fragment oder die Aktivität ist vorhanden oder nicht. Starten Sie die asynctask, indem Sie die schwache Referenz der aufrufenden Entität zuweisen.