2

Ich benutze eine ViewPager um Inhalte anzuzeigen, die von einer Website mit jsoup geholt wurden. In der onCreateView jeder Seite rufe ich eine AsyncTask, die die Daten abruft und aktualisiert die View für jede Seite.Vermeiden Sie die Ausführung von AsyncTask, wenn der ViewPager schnell verschoben wird

Das Problem ist, dass, wenn der Benutzer die Seiten schneller als üblich gleitet die AsyncTask mehrere Male aufgerufen wird und folglich mehrere unbrauchbare Anforderungen mit jsoup gemacht werden, da das einzige nützliche ist das letzte.

Ich versuchte setUserVisibleHint auf der Fragment Klasse und das Hinzufügen von setOnPageChangeListener in der Activity-Klasse, aber diese Methoden machen mir das ViewPager Verhalten der Vorbelastung auf die nächste Seite verlieren, und ich will nicht, dass.

Gibt es eine Möglichkeit zu wissen, wann der Benutzer nicht mehr rutschte und nur die AsynTask in diesem Moment anruft?

public class ScreenSlidePageFragment extends Fragment { 

    public static final String PAGE_NUMBER = "page"; 

    private int mProblemNumber; 

    public static ScreenSlidePageFragment create(int pageNumber) { 
     ScreenSlidePageFragment fragment = new ScreenSlidePageFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(PAGE_NUMBER, pageNumber); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mPageNumber = getArguments().getInt(PAGE_NUMBER); 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     ViewGroup rootView = (ViewGroup) inflater.inflate(
       R.layout.fragment_screen_slide_page, container, false); 
     new GetPageTask(url).execute(); 

     return rootView; 
    } 
} 
+0

Verwendung ein Dummy handler.postdelay (..., delay_ms) oder Countdown-Timer. 1sek Verzögerung sollte gut funktionieren. Wenn Sie nur ein paar Fragmente haben, können Sie viewpager.setoffscreenpacelimit (fragments_count) so einstellen, dass es einmal geladen wird und niemals auf der geänderten Seite initialisiert wird. – uguboz

Antwort

1

Ich denke, der beste Weg, nur zu überprüfen wäre, ob die AsyncTask läuft oder nicht. Speichern Sie einen Verweis auf Ihre AsyncTask und wenn der Benutzer dann zurück zu dieser Seite scrollt, können Sie seinen Status mit AsyncTask.Status (http://developer.android.com/reference/android/os/AsyncTask.Status.html) überprüfen.

Wenn Sie auch vermeiden möchten, neue Aufgaben zu starten, wenn der Benutzer zu schnell scrollt, können Sie handler.postDelayed(yourRunnable, longMs) verwenden. Jedes Mal Benutzer wählt eine Seite, die Sie so etwas tun kann:

handler.removeCallbacks(yourRunnable); 
handler.postDelayed(yourRunnable, longMs); 

diese Weise können Sie vorherige anhängige Aufgabe entfernen wird und eine neue in longMs Zeit einplanen. Z.B. Wenn Sie 1000 ms eingeben, werden Ihre Aufgaben nur in einer Sekunde gestartet, nachdem der Benutzer eine Seite ausgewählt hat.

+0

Wie ich in der anderen Antwort kommentierte, tut 'postDelayed' nicht, was ich will, weil alle verschobenen Seiten die' AsyncTask' nach der angegebenen Zeit sowieso aufrufen. Ist es in Ihrer ersten Lösung möglich, den Status einer anderen AsyncTask als der auf der aktuellen Seite zu überprüfen? Wenn ja, könnte diese Lösung funktionieren. –

+0

Nicht sicher, warum Sie das brauchen würden, aber Sie können ein Array oder eine Liste von 'AsyncTask' haben und die Fragmentposition verwenden, um die benötigte Instanz zu erhalten. Sie können dieses Array in ein umschließendes Fragment/eine Aktivität einfügen. –

0

Möglicherweise möchten Sie die Anforderung zum Abrufen des Inhalts verzögern. Wenn Sie zum Beispiel schnell wischen, warten Sie eine halbe Sekunde, um den Inhalt zu laden (statt sofort), um dem System eine Chance zum Atmen zu geben und zu überprüfen, ob die Seite noch sichtbar ist.

Etwas wie folgt aus:

handler.postDelayed(new Runnable(){ 
    if (isVisible){ 
     new GetPageTask(url).execute(); 
    } 
}, 500); 
+0

Vielen Dank für Ihre Antwort, aber 'postDelayed' tut nicht, was ich will, weil alle verschobenen Seiten die'AsyncTask' nach der angegebenen Zeit aufrufen. –

+0

Würde es? Deshalb überprüfen wir, ob das Fragment sichtbar ist. Wenn das Fragment sichtbar ist, nachdem der Benutzer schnell eine Reihe von Ansichten durchsucht hat, wird die Aufgabe ausgeführt. Andernfalls haben Sie die Ansichten zu schnell übernommen und es passiert nichts (weil 'fragment.isVisible()' fehlschlagen würde). –

Verwandte Themen