2010-12-27 11 views
60

Próbuję wyświetlić niestandardowy progressdialog podczas ładowania kanału RSS z serwera http, wykonałem trudne wyszukiwanie, ale nic mi nie pomogło, jedyne co wiem to to, że rozwiązanie powinno używać AsyncTask, ale jestem mylące o params, aby przejść do tego AsyncTask. Oto moja działalność:progressDialog w AsyncTask

import java.util.ArrayList; 
import java.util.List; 

import com.cyberesa.info.BaseFeedParser; 
import com.cyberesa.info.Message; 
import com.cyberesa.info.MessageListAdapter; 
import com.cyberesa.info.R; 

import android.app.ListActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 

public class Soirees extends ListActivity { 
    private List<Message> messages; 
    private TextView tvSorties; 
    private MyProgressDialog dialog; 
    @Override 
    public void onCreate(Bundle icicle) { 

     super.onCreate(icicle); 

     setContentView(R.layout.sorties); 

     tvSorties=(TextView)findViewById(R.id.TVTitle); 
     tvSorties.setText("Programme des soirées"); 

     loadFeed(); 

    } 

    private void loadFeed(){ 
     try{ 
      BaseFeedParser parser = new BaseFeedParser(); 
      messages = parser.parse(); 
      List<Message> titles = new ArrayList<Message>(messages.size()); 
      for (Message msg : messages){ 
       titles.add(msg); 
      } 
      MessageListAdapter adapter = new MessageListAdapter(this,titles); 
      this.setListAdapter(adapter); 
      adapter.notifyDataSetChanged(); 

     } catch (Throwable t){ 
      Log.e("ImageLoader",t.getMessage(),t); 
     } 
    } 

} 

Czy możesz mi pomóc dodać AsyncTask do tego?

Dziękuję Houssem

Odpowiedz

41

ustalony przez przeniesienie widoku modyfikatory onPostExecute tak stała kod jest:

public class Soirees extends ListActivity { 
    private List<Message> messages; 
    private TextView tvSorties; 

    //private MyProgressDialog dialog; 
    @Override 
    public void onCreate(Bundle icicle) { 

     super.onCreate(icicle); 

     setContentView(R.layout.sorties); 

     tvSorties=(TextView)findViewById(R.id.TVTitle); 
     tvSorties.setText("Programme des soirées"); 

     new ProgressTask(Soirees.this).execute(); 


    } 


    private class ProgressTask extends AsyncTask<String, Void, Boolean> { 
     private ProgressDialog dialog; 
     List<Message> titles; 
     private ListActivity activity; 
     //private List<Message> messages; 
     public ProgressTask(ListActivity activity) { 
      this.activity = activity; 
      context = activity; 
      dialog = new ProgressDialog(context); 
     } 



     /** progress dialog to show user that the backup is processing. */ 

     /** application context. */ 
     private Context context; 

     protected void onPreExecute() { 
      this.dialog.setMessage("Progress start"); 
      this.dialog.show(); 
     } 

      @Override 
     protected void onPostExecute(final Boolean success) { 
       List<Message> titles = new ArrayList<Message>(messages.size()); 
       for (Message msg : messages){ 
        titles.add(msg); 
       } 
       MessageListAdapter adapter = new MessageListAdapter(activity, titles); 
       activity.setListAdapter(adapter); 
       adapter.notifyDataSetChanged(); 

       if (dialog.isShowing()) { 
       dialog.dismiss(); 
      } 

      if (success) { 
       Toast.makeText(context, "OK", Toast.LENGTH_LONG).show(); 
      } else { 
       Toast.makeText(context, "Error", Toast.LENGTH_LONG).show(); 
      } 
     } 

     protected Boolean doInBackground(final String... args) { 
      try{  
       BaseFeedParser parser = new BaseFeedParser(); 
       messages = parser.parse(); 


       return true; 
      } catch (Exception e){ 
       Log.e("tag", "error", e); 
       return false; 
      } 
      } 


    } 

} 

@Vladimir, thx kod był bardzo pomocny.

+3

ok, upvote lub mark as solution =) –

+0

Nie można utworzyć programu obsługi wewnątrz wątek, który nie nazwał Looper.prepare() Otrzymuję ten błąd. jak rozwiązać ten problem. – Noby

+0

Myślę, że musisz dodać do tego jeszcze jedną rzecz. Musisz utworzyć globalny prywatny obiekt do AsyncTask, a gdy działanie zostanie zniszczone, anuluj AsyncTask. W twoim przypadku, jeśli użytkownik naciśnie przycisk Wstecz przed zakończeniem zadania AsyncTask, najprawdopodobniej nastąpi awaria aplikacji. – tasomaniac

123
/** 
* this class performs all the work, shows dialog before the work and dismiss it after 
*/ 
public class ProgressTask extends AsyncTask<String, Void, Boolean> { 

    public ProgressTask(ListActivity activity) { 
     this.activity = activity; 
     dialog = new ProgressDialog(activity); 
    } 

    /** progress dialog to show user that the backup is processing. */ 
    private ProgressDialog dialog; 
    /** application context. */ 
    private ListActivity activity; 

    protected void onPreExecute() { 
     this.dialog.setMessage("Progress start"); 
     this.dialog.show(); 
    } 

     @Override 
    protected void onPostExecute(final Boolean success) { 
     if (dialog.isShowing()) { 
      dialog.dismiss(); 
     } 


     MessageListAdapter adapter = new MessageListAdapter(activity, titles); 
     setListAdapter(adapter); 
     adapter.notifyDataSetChanged(); 


     if (success) { 
      Toast.makeText(context, "OK", Toast.LENGTH_LONG).show(); 
     } else { 
      Toast.makeText(context, "Error", Toast.LENGTH_LONG).show(); 
     } 
    } 

    protected Boolean doInBackground(final String... args) { 
     try{  
      BaseFeedParser parser = new BaseFeedParser(); 
      messages = parser.parse(); 
      List<Message> titles = new ArrayList<Message>(messages.size()); 
      for (Message msg : messages){ 
       titles.add(msg); 
      } 
      activity.setMessages(titles); 
      return true; 
     } catch (Exception e) 
      Log.e("tag", "error", e); 
      return false; 
     } 
    } 
} 

public class Soirees extends ListActivity { 
    private List<Message> messages; 
    private TextView tvSorties; 
    private MyProgressDialog dialog; 
    @Override 
    public void onCreate(Bundle icicle) { 

     super.onCreate(icicle); 

     setContentView(R.layout.sorties); 

     tvSorties=(TextView)findViewById(R.id.TVTitle); 
     tvSorties.setText("Programme des soirées"); 

     // just call here the task 
     AsyncTask task = new ProgressTask(this).execute(); 
    } 

    public void setMessages(List<Message> msgs) { 
     messages = msgs; 
    } 

} 
+0

Dziękuję wam, więc próbuję tego, a jak zapytałem, które parametry mam tu przekazać? protected Boolean doInBackground (final String ... args), ponieważ linia adapter MessageListAdapter = new MessageListAdapter (ten, tytuły) zgłasza błąd – Houssem

+0

aktywność będzie wystarczająca. wystarczy ustawić adapter listy. –

+0

Przepraszam Vlad, jestem całkowicie zdezorientowany: S (początkujący przypadek) – Houssem

3

Kilka dni temu znalazłem bardzo ładne rozwiązanie tego problemu. Przeczytaj o tym here. W dwóch słowach Mike stworzył AsyncTaskManager, który pośredniczy w ProgressDialog i AsyncTask. Jest bardzo łatwy w użyciu tego rozwiązania. Wystarczy, że włączysz do swojego projektu kilka interfejsów i kilka klas, a w twojej działalności napisz prosty kod i zagnieżdż nowy AsyncTask z BaseTask. Radzę także, abyś czytał komentarze, ponieważ są tam przydatne wskazówki.

8

AsyncTask jest bardzo pomocny!

class QueryBibleDetail extends AsyncTask<Integer, Integer, String>{ 
     private Activity activity; 
     private ProgressDialog dialog; 
     private Context context; 

     public QueryBibleDetail(Activity activity){ 
      this.activity = activity; 
      this.context = activity; 
      this.dialog = new ProgressDialog(activity); 
      this.dialog.setTitle("查询经文"); 
      this.dialog.setMessage("正在查询:"+tome+chapterID+":"+sectionFromID+"-"+sectionToID); 
      if(!this.dialog.isShowing()){ 
       this.dialog.show(); 
      } 
     } 

     @Override 
     protected String doInBackground(Integer... params) { 
      Log.d(TAG,"经文doInBackground"); 
      publishProgress(params[0]); 

      if(sectionFromID > sectionToID){ 
       return ""; 
      } 

      String queryBible = "action=query_bible&article="+chapterID+"&id="+tomeID+"&verse_start="+sectionFromID+"&verse_stop="+sectionToID+""; 
      try{ 
       String bible = (Json.getRequest(HOST+queryBible)).trim(); 
       bible = android.text.Html.fromHtml(bible).toString(); 
       return bible; 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(String bible){ 
      Log.d(TAG,"经文onPostExecute"); 
      TextView bibleBox = (TextView) findViewById(R.id.bibleBox); 
      bibleBox.setText(bible); 
      this.dialog.dismiss(); 
     } 
    } 
0

Minęło kilka lat, odkąd zadano to pytanie (i od kiedy ktoś wysłał odpowiedź). Od tego czasu ProgressDialog został wycofany na poziomie API O, zgodnie z Android's official documentation. Jako takie, można rozważyć użycie an inline progress bar zamiast ProgressDialog, jak sugerują autorzy dokumentacji.

-1

Na to pytanie już udzielono odpowiedzi, a większość odpowiedzi tutaj jest poprawna, ale nie rozwiązują one jednego poważnego problemu związanego ze zmianami konfiguracji. Spójrz na ten artykuł https://androidresearch.wordpress.com/2013/05/10/dealing-with-asynctask-and-screen-orientation/, jeśli chcesz napisać zadanie asynchroniczne w lepszy sposób.

+0

@ Którzy kiedykolwiek głosowali na to. Czy możesz mi powiedzieć, co jest nie tak z tą odpowiedzią? To jeden z dobrych artykułów, które przeczytałem i chciałbym podzielić się z pośrednimi programistami. – Prakash