2013-03-14 10 views
8

Zastanawiam się, czy został użyty AsyncTask do użycia w głównej czynności (MainActivity.java) z uruchomieniem wątku.Czy powinienem używać klasy AsyncTask w działaniu rozszerzającym MainActivity?

Na przykład zauważyłem wiele tutoriali przy użyciu AsyncTask deklarują prywatną klasę wewnątrz główne klasy rozszerzające Activity zamiast tworzenia niezależnego pliku .java dla tego AsyncTask (MyAsyncTask.java) class.

Ale zauważyłem, że podczas korzystania z niezależnego pliku Nie jestem w stanie uruchomić runOnUIThread(), ponieważ należy do klasy Activity, więc jak będę mógł skorzystać z tej metody wewnątrz tej niezależnej AsyncTask (MyAsyncTask. java), który rozszerza się o AsyncTask, a nie o Activity.

+0

dlaczego chcesz wywołać runOnUIThread z AsyncTask? – EvilDuck

+0

aby zmienić TextViews, nie można ich zmienić z innych wątków. – Alex

+0

Możesz zaktualizować interfejs w onPostExecute i onPreExecute –

Odpowiedz

12

To jest całkowicie w porządku. Robię to często, ale zależy to od tego, jak go używasz. Jeśli może być użyty przez inne Activities, to podaję mu własną klasę lub klasę dzieloną. Ale jeśli jest to do jednego celu, uczyniłbym go wewnętrzną klasą MainActivity.

Zaletą utworzenia klasy wewnętrznej jest to, że ma bezpośredni dostęp do zmiennych członków klasy. Jeśli utworzysz oddzielną klasę, musisz utworzyć konstruktor, jeśli musisz przekazać params, na przykład context lub inne zmienne.

Nie wiem dokładnie, co robisz, ale nie jestem pewien, czy potrzebujesz runOnUiThread(). Możesz utworzyć konstruktora w pliku AsyncTask i zaakceptować go jako parametr i cokolwiek innego potrzebujesz. Następnie można zaktualizować Przykład UI w onPostExecute()

Public class MyAsyncTask extends AsyncTask 
{ 

private Context context; 

public MyAsyncTask(Context context) { // can take other params if needed 
    this.context = context; 
} 

// Add your AsyncTask methods and logic 
//you can use your context variable in onPostExecute() to manipulate activity UI 
}` 

następnie wywołać go w MainActivity

MyAsyncTask myTask = new MyAsyncTask(this); //can pass other variables as needed 
myTask.execute(); 
+0

dziękuję za odpowiedź, podoba mi się, problem polega na tym, że runOnUIThread() nie może zostać uruchomiony, jeśli jest to niezależny plik, będę musiał użyć tej wewnętrznej klasy, której nie chcę, ponieważ użyję tego samego klasa dla 3 działań, i nie umieszczę całego kodu AsyncTask w każdym działaniu – Alex

+0

Nie musisz używać wewnętrznej klasy. Przekaż odwołanie do działania jako parametru w konstruktorze (tak jak to opisuje kodMagic). Następnie użyj odwołania do działania, aby wywołać metodę runOnUIThread(). – Sababado

+1

Dziękuję, że działało z onPostExecute()! – Alex

2

wierzę w większości tutoriali odbierają to, co jest najłatwiejsze do zrozumienia/odczytu, nie to, co jest najlepsze.

Z klasą wewnętrzną przechowujesz zmienne działania, co może być prostsze.

Ogólnie rzecz biorąc, powinieneś hermetyzować jak najwięcej, także AsyncTasks, aby móc ponownie użyć ich z dowolnego innego punktu w kodzie.

+0

tak, dlatego chciałbym zrobić niezależny plik dla niego, więc mogę go używać nie tylko w jednym celu, ale także dla wielu celów – Alex

2

Tak Można utworzyć AsyncTask class w swoim MainActivity.java.

public class CategoryListScreen extends Activity { 


    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
    new loadcategory().execute(); 
} 
class loadcategory extends AsyncTask<Void, Void, Void> { 

@Override 
     protected Void doInBackground(Void... params) { } 

protected void onPostExecute(Void param) { } 
    } // AsyncTask over 
}//main class over 
+0

chodzi o to, że nie chcę go używać jako wewnętrzna klasa. Chcę użyć go jako osobnej klasy. – Alex

4

Ogólnie kładziemy AsyncTask w tej samej klasie, aby uczynić go bardziej jasne, że jest on używany tylko przez taką samą działalność.

Jeśli chcesz, aby AsyncTask Tobe ponownie wykorzystane przez więcej niż jednej czynności niż można po prostu stworzyć niezależną klasę i przekazać parametry z działalności przez konstruktorów

Można utworzyć interfejs w asyncTask wysłać odpowiedź z asynctask do twoja aktywność jak poniżej i wywołaj metodę lister, gdy jest to wymagane.Nazwałem go onPostExecute():

public class DeckDownloader extends AsyncTask<Void, Void, String> { 

    OnDownloadUpdateListener listener; 

    public interface OnDownloadUpdateListener { 
     public void OnDownloadDeckFinish(String Response);  
    } 


    public DeckDownloader(Context ctx, OnDownloadUpdateListener listener) { 
     mContext = ctx; 
     this.listener = listener; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
     String str = "downloading"; 
     //your async code goes here 
     return str; 
    } 

    @Override 
    protected void onPreExecute() { 
      super.onPreExecute(); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
      if(listener != null) { 
       listener.OnDownloadDeckProgress(result); 
      } 
    } 
} 

A w klasie aktywny, trzeba wdrożyć tę słuchacza i napisać kod do aktualizacji TextView w tym sposobie realizacji:

public class myActivity extends Activity{ 
      private DeckDownloader.OnDownloadUpdateListener downloadListener; 
      TextView txtAsyncResponse; 

      @Override 
      public void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       txtAsyncResponse = (TextView) findViewById(R.id.txtAsyncResponse); 


      downloadListener = new DeckDownloader.OnDownloadUpdateListener() { 
       @Override 
       public void OnDownloadDeckFinish(String Response) { 
        txtAsyncResponse.setText(Response); 
       } 
      }; 
    } 

I można napisać poniżej kod aby rozpocząć AsyncTask w swojej działalności na każde żądanie jak przycisk kliknij zdarzenie lub inny

DeckDownloader mTask = new DeckDownloader(this.getApplicationContext(), downloadListener); 
mTask.execute(); 

To może być thindg chcesz!

+0

i jak mogę wtedy zmienić widoki? Nie mogę uruchomić metody runOnUIThread(), jeśli jest to niezależna klasa. – Alex

+0

dlaczego używasz runOnUIThread? jaki jest na to wymóg? –

+1

Czytałem twój komentarz, o którym mowa, że ​​coś, czego potrzebujesz, aby zmienić zawartość textview jest w aktywności dzwoniącego po zakończeniu AsyncTask? Czy moje zrozumienie jest poprawne? –

Powiązane problemy