android AsyncTask wysyłanie wywołań zwrotnych do interfejsu użytkownika [duplikat]
To pytanie ma już odpowiedź tutaj:
- Jak uzyskać wynik OnPostExecute() do głównej aktywności, ponieważ AsyncTask jest oddzielną klasą? 14 odpowiedzi
Mam następującą klasę asynctask, która nie znajduje się wewnątrz aktywności. W aktywności inicjuję asynctask i chcę, aby asynctask zgłaszał wywołania zwrotne z powrotem do mojej aktywności. Na to możliwe? A może asynctask musi znajdować się w tym samym pliku klasy co aktywność?
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
caller.sometextfield.setText("bla");
}
Coś takiego? 4 answers
Możesz utworzyć interface
, przekazać ją do AsyncTask
(w konstruktorze), a następnie wywołać metodę w onPostExecute()
Na przykład:
Twój interfejs:
public interface OnTaskCompleted{
void onTaskCompleted();
}
Twoja Aktywność:
public class YourActivity implements OnTaskCompleted{
// your Activity
}
I twoja AsyncTask:
public class YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
private OnTaskCompleted listener;
public YourTask(OnTaskCompleted listener){
this.listener=listener;
}
// required methods
protected void onPostExecute(Object o){
// your stuff
listener.onTaskCompleted();
}
}
EDIT
Ponieważ ta odpowiedź stała się dość popularna, chcę dodać kilka rzeczy.
Jeśli jesteś nowy w rozwoju Androida, AsyncTask
to szybki sposób, aby wszystko działało bez blokowania wątku UI. Rozwiązuje pewne problemy rzeczywiście, nie ma nic złego w tym, jak klasa sama działa. Jednak przynosi to pewne implikacje, takie jak:
- możliwość wycieków pamięci. Jeśli zachowasz odniesienie do
Activity
, pozostanie ono w pamięci nawet po opuszczeniu ekranu przez użytkownika (lub obróceniu urządzenia). -
{[4] } nie dostarcza wyniku
Activity
, JeśliActivity
zostało już zniszczone. Musisz dodać dodatkowy kod, aby zarządzać wszystkimi tymi rzeczami lub zrobić operacje dwa razy. - zawiły kod, który robi wszystko w
Activity
Kiedy czujesz, że dojrzałeś na tyle, aby ruszyć dalej z Androidem, spójrz na ten artykuł który, myślę, jest lepszym sposobem na tworzenie aplikacji na Androida z operacjami asynchronicznymi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 13:31:03
Czułem, że poniższe podejście jest bardzo łatwe.
I have declared an interface for callback
public interface AsyncResponse {
void processFinish(Object output);
}
Następnie utworzono zadanie asynchroniczne do odpowiadania na wszystkie typy równoległych żądań
public class MyAsyncTask extends AsyncTask<Object, Object, Object> {
public AsyncResponse delegate = null;//Call back interface
public MyAsyncTask(AsyncResponse asyncResponse) {
delegate = asyncResponse;//Assigning call back interfacethrough constructor
}
@Override
protected Object doInBackground(Object... params) {
//My Background tasks are written here
return {resutl Object}
}
@Override
protected void onPostExecute(Object result) {
delegate.processFinish(result);
}
}
Następnie wywołane zadanie asynchroniczne po kliknięciu przycisku w klasie activity.
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
Button mbtnPress = (Button) findViewById(R.id.btnPress);
mbtnPress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {
@Override
public void processFinish(Object output) {
Log.d("Response From Asynchronous task:", (String) output);
mbtnPress.setText((String) output);
}
});
asyncTask.execute(new Object[] { "Youe request to aynchronous task class is giving here.." });
}
});
}
}
Dzięki
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 14:34:37
W uzupełnieniu do powyższych odpowiedzi, Możesz również dostosować swoje zastępcze dla każdego wywołania asynchronicznego, tak aby każde wywołanie ogólnej metody asynchronicznej wypełniało różne dane, w zależności od rzeczy onTaskDone, które tam umieściłeś.
Main.FragmentCallback FC= new Main.FragmentCallback(){
@Override
public void onTaskDone(String results) {
localText.setText(results); //example TextView
}
};
new API_CALL(this.getApplicationContext(), "GET",FC).execute("&Books=" + Main.Books + "&args=" + profile_id);
Przypomnij: użyłem interfejsu na głównej aktywności, do której przychodzi "Main", Tak:
public interface FragmentCallback {
public void onTaskDone(String results);
}
Mój post API wygląda tak:
@Override
protected void onPostExecute(String results) {
Log.i("TASK Result", results);
mFragmentCallback.onTaskDone(results);
}
Konstruktor API wygląda tak:
class API_CALL extends AsyncTask<String,Void,String> {
private Main.FragmentCallback mFragmentCallback;
private Context act;
private String method;
public API_CALL(Context ctx, String api_method,Main.FragmentCallback fragmentCallback) {
act=ctx;
method=api_method;
mFragmentCallback = fragmentCallback;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-28 10:34:11
Powtórzę to, co powiedzieli inni, ale postaram się to uprościć...
Najpierw Utwórz klasę interfejsu
public interface PostTaskListener<K> {
// K is the type of the result object of the async task
void onPostTask(K result);
}
Po Drugie, Utwórz AsyncTask (która może być wewnętrzną klasą statyczną Twojej aktywności lub fragmentu), która używa interfejsu, włączając konkretną klasę. W przykładzie, PostTaskListener jest parametryzowany za pomocą String, co oznacza, że oczekuje klasy String w wyniku zadania asynchronicznego.
public static class LoadData extends AsyncTask<Void, Void, String> {
private PostTaskListener<String> postTaskListener;
protected LoadData(PostTaskListener<String> postTaskListener){
this.postTaskListener = postTaskListener;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null && postTaskListener != null)
postTaskListener.onPostTask(result);
}
}
Wreszcie część, w której połączysz swoje logika. W ćwiczeniu / fragmencie Utwórz posttasklistener i przekaż go do zadania asynchronicznego. Oto przykład:
...
PostTaskListener<String> postTaskListener = new PostTaskListener<String>() {
@Override
public void onPostTask(String result) {
//Your post execution task code
}
}
// Create the async task and pass it the post task listener.
new LoadData(postTaskListener);
Zrobione!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-11 13:17:42