Il mio problema riguarda un'attività che ospita tre frammenti di supporto. Uno è un normale frammento programmatico (chiamiamolo un frammento di casa). Uno è un frammento di ritratto aggiunto sopra il frammento di casa quando il dispositivo è orientato e uno è "senza testa", per continuare un'attività asincrona indipendentemente dalle modifiche di configurazione. Molto semplice, stavo lavorando su this nice example.findFragmentByTag null per Fragment A, se setRetain (true) su Fragment B
public class HeadlessCustomerDetailFetchFragment extends Fragment{
private RequestCustomerDetails mRequest;
private AsyncFetchCustomerDetails mAsyncFetchCustomerDetails;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
mRequest = (RequestCustomerDetails)getActivity();
}
public void startFetching(String scannedBarcode) {
if(mAsyncFetchCustomerDetails != null && mAsyncFetchCustomerDetails.getStatus() == AsyncTask.Status.RUNNING) return;
if(mAsyncFetchCustomerDetails == null || mAsyncFetchCustomerDetails.getStatus() == AsyncTask.Status.FINISHED)
mAsyncFetchCustomerDetails = new AsyncFetchCustomerDetails(getActivity(), mRequest, mPartner, scannedBarcode);
}
public void stopFetching() {
if(mAsyncFetchCustomerDetails != null && mAsyncFetchCustomerDetails.getStatus() != AsyncTask.Status.RUNNING) return;
mAsyncFetchCustomerDetails.cancel(true);
}
}
In onCreate di mia attività() creo e aggiungi il frammento senza testa, se necessario.
mHeadlessCustomerDetailFetchFragment = (HeadlessCustomerDetailFetchFragment)getSupportFragmentManager()
.findFragmentByTag(HeadlessCustomerDetailFetchFragment.class.getSimpleName());
if(mHeadlessCustomerDetailFetchFragment == null) {
mHeadlessCustomerDetailFetchFragment = HeadlessCustomerDetailFetchFragment.instantiate(this, HeadlessCustomerDetailFetchFragment.class.getName());
getSupportFragmentManager().beginTransaction()
.add(mHeadlessCustomerDetailFetchFragment, mHeadlessCustomerDetailFetchFragment.getClass().getSimpleName())
.commit();
getSupportFragmentManager().executePendingTransactions();
id = null;
}
Allora lancio un compito asincrona (via() funzione mio startFetching) dopo un ritardo di 6 secondi (per la prova) ha dato il via nel onCreateView() del frammento ritratto che viene aggiunto quando cambia l'orientamento a ritratto . La variazione dell'orientamento viene rilevata onCreate della attività():
if (savedInstanceState == null) {
// Do some initial stuff for the home fragment
}
else {
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//Launch portrait fragment
FragmentLauncher.launchPortraitFragment(this);
}
Quando l'operazione è terminata, ritorno all'attività e tentare di aggiornare l'interfaccia utente del frammento ritratto attivo, ma il direttore frammento non può trovare, findFragmentByTag() restituisce null.
Per essere chiari:
- Il tag è corretta
- Il frammento si trova se lo faccio non orientare il dispositivo, e invece dare il via l'operazione asincrona da qualche altra parte, durante onResume la propria attività () per esempio.
- Se non dico al frammento senza testa di conservare se stesso - perdendo così il vantaggio di non ricrearlo, anche il frammento di ritratto viene trovato correttamente.
- Debugaggio È possibile visualizzare tutti i 3 frammenti nel gestore se l'unità senza testa non è impostata per conservare se stessa. Se lo è, posso solo vedere il frammento senza testa.
Forse conservare un frammento in modo aggressivo uccide altri frammenti che non vengono conservati o qualcosa del genere?
Perché non puoi semplicemente eseguire il tuo asynctask in un servizio ?. Credo che questo elimina il tuo problema di rotazione ed è anche un modo più ordinato per farlo ?. – Smashing
Lo penso anch'io - non ne so molto dei servizi e mi è sembrato eccessivo per un compito, ma potrebbe essere la mia unica opzione - lo esamineremo grazie a –
Coolbeans. Fammi sapere se hai bisogno di aiuto. – Smashing