2017-11-15 5 views
0

Ich habe viele Fragen zu AsyncTask Probleme der verschiedenen Arten gelesen, aber ich scheine nicht das Problem zu finden, die ich konfrontiert bin.Statische AsyncTask und findViewById()

Android Studio besteht darauf, meine benutzerdefinierte AsyncTask statisch mit folgendem Hinweis zu machen:

Dieser AsyncTask Klasse statisch sein sollte oder Leck

Aus diesem Grunde auftreten könnte ich versucht habe über die Verwendung WeakReference auf die Aktivität, in der die Aufgabe ausgeführt wird. Problem ist, dass ich findViewById() in OnPre und OnPostExecute verwenden möchte und ich nicht auf die Methode zugreifen kann. Ich habe festgestellt, dass:

weakReference.get().findViewById(R.id.dictionaryLoading).setVisibility(View.VISIBLE); 

keinen Fehler in Android Studio produzieren, aber es stürzt die App.

Wie löst man das Problem, in der benutzerdefinierten statischen AsyncTask nicht auf findViewById() zuzugreifen?

-Code funktioniert in der Regel, wenn ich von WeakReference loswerden und machen AsyncTask es nicht statische

Hier ist meine AsyncTask: (die leere while-Schleife absichtlich gibt es so wartet sie, bis die globale Variable einige Daten hat

.
public static class LoadingDictionaryAsync extends AsyncTask<Void, Void, Void> { 

    private final WeakReference<MainScreenActivity> weakReference; 

    private LoadingDictionaryAsync(MainScreenActivity mainScreenActivity){ 
     this.weakReference = new WeakReference<>(mainScreenActivity); 
    } 


    @Override 
    protected void onPreExecute() { 
     weakReference.get().findViewById(R.id.dictionaryLoading).setVisibility(View.VISIBLE); 
     weakReference.get().findViewById(R.id.dictionaryListView).setVisibility(View.GONE); 
    } 

    @Override 
    protected Void doInBackground(Void... voids) { 

     if (vocabulariesGlobal == null || vocabulariesGlobal.size() == 0) { 
      weakReference.get().loadDatabaseVocabularyToDictionary(); 
     } 

     while (vocabulariesGlobal == null || vocabulariesGlobal.size() == 0) { 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     weakReference.get().loadDictionaryOnTheList(vocabulariesGlobal); 
     weakReference.get().findViewById(R.id.dictionaryLoading).setVisibility(View.GONE); 
     weakReference.get().findViewById(R.id.dictionaryListView).setVisibility(View.VISIBLE); 
    } 
} 

Und das ist, wie ich es nenne:

LoadingDictionaryAsync loadingDictionaryAsync = new LoadingDictionaryAsync((MainScreenActivity)getParent()); 
loadingDictionaryAsync.execute(); 

EDIT:

Ich habe versucht, mit der Erstellung einer separaten Datei mit der LoadingDictionaryAsync, wo statische ist kein Problem mehr, aber ich habe immer noch Probleme mit der Übergabe MainScreenActivity es, so findViewById() kann nicht verwendet werden.

Was ist die richtige Art der Weitergabe von Aktivitäten? Ich möchte es in onNavigationItemSelected() und onQueryTextChange() in SearchView übergeben?

+1

Haben Sie einen Kontextparameter anstelle dieser schwachen Referenz versucht? – greenapps

+1

'aber es stürzt die App' post die Logcat-Details –

+1

' (MainScreenActivity) getParent() '. Von wo rufst du das an? – greenapps

Antwort

0

Ich habe das Problem auf folgende Weise festgelegt:

  1. Verschoben Async Klassen I bis separate Dateien erstellt haben.
  2. Switched die Verwendung von WeakReference zu Context
  3. vorangestelltem findViewById() mit
  4. die AsyncTasks mit MainScreenActivity.this Called

So der Aufruf:

LoadingDictionaryAsync loadingDictionaryAsync = new LoadingDictionaryAsync(MainScreenActivity.this); 
loadingDictionaryAsync.execute(); 

Und nun die Die AsyncTask-Klasse sieht folgendermaßen aus:

public class LoadingDictionaryAsync extends AsyncTask<Void, Void, Void> { 


private Context context; 
    public LoadingDictionaryAsync(Context context) { 
     this.context = context; 
    } 

@Override 
protected void onPreExecute() { 

    ((MainScreenActivity)context).findViewById(R.id.dictionaryLoading).setVisibility(View.VISIBLE); 
    ((MainScreenActivity)context).findViewById(R.id.dictionaryListView).setVisibility(View.GONE); 
} 

@Override 
protected Void doInBackground(Void... voids) { 


    if (((MainScreenActivity)context).vocabulariesGlobal == null || ((MainScreenActivity)context).vocabulariesGlobal.size() == 0) { 
     ((MainScreenActivity)context).loadDatabaseVocabularyToDictionary(); 
    } 
    while (((MainScreenActivity)context).vocabulariesGlobal == null || ((MainScreenActivity)context).vocabulariesGlobal.size() == 0) { 
    } 
    return null; 
} 

@Override 
protected void onPostExecute(Void aVoid) { 

    ((MainScreenActivity)context).loadDictionaryOnTheList(((MainScreenActivity)context).vocabulariesGlobal); 
    ((MainScreenActivity)context).findViewById(R.id.dictionaryLoading).setVisibility(View.GONE); 
    ((MainScreenActivity)context).findViewById(R.id.dictionaryListView).setVisibility(View.VISIBLE); 
} 
}