0

Ich möchte einen Ladedialog anzeigen, wenn der Benutzer zurück zu meinem activity vor der Wiederaufnahme der activity navigiert - ist das möglich?Laden des Bildschirms vor dem Fortsetzen einer Aktivität

Hier ist ein Hintergrund - wenn die Aktivität zum ersten Mal gestartet wird, wird ein Ladevorgang dialog angezeigt, während ein Cache-Status aus einer Datei geladen wird. Dies dauert bei neueren Telefonen weniger als eine Sekunde, kann jedoch bei älteren Modellen länger dauern und ist für die Ausführung auf dem UI-Thread in jedem Fall zu lang. Der zwischengespeicherte Status kann durch den Garbage Collector zerstört werden (oder der Prozess kann abgebrochen werden), bevor der Benutzer zu der Aktivität zurück navigiert, was zu Problemen beim Wiederaufnehmen der Aktivität führt. Im Speziellen beginnen wiederhergestellte Fragmentlebenszyklusereignisse innerhalb der onCreate-Methode der Aktivität und hängen stark vom zwischengespeicherten Status ab. Im Idealfall sollte ein Ladedialog angezeigt werden und die Lebenszyklusereignisse von Kind fragments sollten verzögert werden, bis der zwischengespeicherte Zustand wiederhergestellt ist.

Alternativ könnte ich überprüfen, ob diese Ressourcen vor der Initialisierung jedes Fragments/Aktivität verfügbar sind, aber wenn dieser Ansatz verwendet würde, müsste die Wiederherstellung des Fragmentstatus wahrscheinlich erst nach onResume verzögert werden - das würde ich erwarten Bei Problemen, die den von den Elternklassen des Fragments verwendeten Status der gespeicherten Instanz wiederherstellen. Bietet das Framework Möglichkeiten, dies zu erleichtern?

UPDATE

A (contrived) Beispiel ist unten angegeben - die Tätigkeit zeigt einen Ladedialog woraufhin eine Schaltfläche angezeigt wird, ein Dialog-Fragment zu erzeugen. An diesem Punkt wird die Aktivität beendet und neu gestartet; Wie erwartet wird der Testdialog automatisch wiederhergestellt, bevor der Ladedialog abgeschlossen ist. Die Frage ist, wie kann dieser Prozess (oder kann) verzögert werden, so dass der Ladedialog abgeschlossen wird, bevor der Testdialog wiederhergestellt wird.

Die Aktivitätsklasse:

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = MainActivity.class.getSimpleName(); 
    private ProgressDialog dialog_ = null; 
    private Button button_ = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.v(TAG, "onCreate: start"); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     button_ = (Button)findViewById(R.id.testButton); 

     // A loading dialog is displayed when the activity is created if the cached state is null 
     if (State.get() == null) { 
      // Using a button here instead of some content fragment for convenience 
      button_.setVisibility(View.GONE); 

      // Create a loading dialog 
      dialog_ = new ProgressDialog(this); 
      dialog_.setMessage("Loading..."); 
      dialog_.setIndeterminate(true); 
      dialog_.show(); 

      // Create the cached state in a background thread 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        Log.v(TAG, "State.create: start"); 
        State.create(MainActivity.this); 
        Log.v(TAG, "State.create: end"); 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          if (dialog_ != null) { 
           dialog_.dismiss(); 
           dialog_ = null; 
          } 

          // When the loading dialog is finished the content fragment is loaded; 
          // here the button is merely displayed. Ideally the life-cycle events 
          // in TestDialog should not be called until after this point. 
          button_.setVisibility(View.VISIBLE); 
          Log.v(TAG, "Loading finished"); 
         } 
        }); 
       } 
      }).start(); 
     } 
     Log.v(TAG, "onCreate: end"); 
    } 

    public void handleTestButton (final View view) { 
     Log.v(TAG, "handleTestButton"); 

     // A dialog fragment is added here; the framework will automatically restore the fragment 
     // if the activity is terminated and restored. 
     new TestDialog().show(getSupportFragmentManager(), null); 
    } 
} 

Der Test-Dialog:

public class TestDialog extends DialogFragment { 
    private static final String TAG = TestDialog.class.getSimpleName(); 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     if (State.get() == null) 
      Log.w(TAG, "onAttach: state was null"); 
    } 

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

     if (State.get() == null) 
      Log.w(TAG, "onCreate: state was null"); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     if (State.get() == null) 
      Log.w(TAG, "onCreateView: state was null"); 

     return inflater.inflate(R.layout.test_dialog, container, false); 
    } 
} 

Der Shared-Zustand:

public class State { 
    private static Object state_ = null; 

    // A long running process is performed on a background thread; locking omitted for clarity 
    public static void create (final Context context) { 
     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
     } 

     state_ = new Object(); 
    } 

    // Fragment life-cycle events require the cached state 
    public static Object get() { 
     return state_; 
    } 
} 

Wenn die oben folgend ausgeführt wird anfänglich hergestellt wird:

onCreate: start 
onCreate: end 
State.create: start 
State.create: end 
Loading finished 
handleTestButton 

Nach Beendigung und Neubelebung der App die folgenden hergestellt:

onCreate: start 
onAttach: state was null 
onCreate: state was null 
onCreate: end 
State.create: start 
onCreateView: state was null 
State.create: end 
Loading finished 

Antwort

0

Sie die Logik der zur Befestigung der Fragmente auf Ihre Aktivität onResume() Methode von Ihrem onCreate() Methode bewegen kann, weil es auch bei der aufgerufen wird, Zeitpunkt des Beginns einer Aktivität zum ersten Mal.

Nun, da Ihre Logik in onResume() ist, können Sie eine ProgressDialod anzeigen, sobald onResume aufgerufen wird. Dann müssen Sie überprüfen, wann Ihre gecachten Daten vollständig geladen sind. Wenn es vollständig geladen ist, können Sie die ProgressDialog ablehnen und die Logik zum Anhängen der Fragmente schreiben.

Ich nehme an, dass Sie einige Rückrufe erhalten können, wenn das Laden beendet ist. Wenn dies nicht der Fall ist, müssen Sie diese Ereignisse möglicherweise verketten.

+0

Die gespeicherten Fragmente werden in der onCreate-Methode der Aktivität vor jeder offenen Aktion (d. H. Nicht als Reaktion auf eine explizite Fragmenttransaktion oder ähnliches) wiederhergestellt (dh ihre Lebenszyklusereignisse beginnen zu feuern). Könnten Sie das erklären? –

+0

Ich dachte, dass Sie die Fragmente explizit anhängen, wenn es automatisch passiert, dann wird es wahrscheinlich nicht funktionieren. Wenn Sie den Code posten können, könnte ich einen Blick darauf werfen. –

+0

Es passiert automatisch; 'onCreate' in' FragmentActivity' ruft beispielsweise die 'onAttach' und' onCreate' Methoden des Fragments auf. Das Projekt ist viel zu groß, um es zu posten, aber ich werde versuchen, ein motivierendes Beispielprojekt zu entwickeln, um meine Frage zu klären. –