2010-11-13 3 views
2

Уважаемые Android-хакеры, Я пытаюсь сделать следующее в своем приложении для Android: когда пользователь нажимает на элемент списка в ListActivity, должен появиться индикатор ProgressDialog, необходимо предусмотреть предварительную загрузку и после сделано, другое действие должно быть вызвано с использованием намерения.Android: проблемы с ProgressDialog

Я пробовал разные подходы. Что совсем не сработало, это использование Async Task. По-видимому, я не могу показать, отклонить или изменить мой ProgressDialog из задачи Async, если этот класс не является членом моей первоначальной деятельности.

я перешел на простую тему тогда, это, как я пытаюсь сделать это:

dialog = ProgressDialog.show(BookmarkActivity.this, "", "Loading...",true); 
new Thread() { 
    public void run() { 
     // do something 
     dialog.setMessage("Change Message..."); 
     // do more 
     dialog.dismiss(); 
     // ... 
     Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class); 
     BookmarkActivity.this.startActivity(intent); 
    } 
}.start(); 

Это работает почти, но изменение диалогового сообщения нет. Я получаю ошибки, говорящие о «просочившихся окнах». (Я могу опубликовать полный журнал, если это необходимо).

Мои вопросы:

  • Как я могу использовать Async Task для этого, где класс имеет свой собственный файл?
  • Как я могу изменить ProgressDialog из моего потока или AsyncTask, не вызывая ошибки при изменении пользовательского интерфейса в другом потоке?

Заранее спасибо, Ян Оливер


Хорошо, с помощью Джейсона, я собрал эту Async задачу. Это работает!

public class ThreadPreLoader extends AsyncTask<Object, String, Void> { 

    private Activity mActivity; 
    private ProgressDialog mDialog; 

    public ThreadPreLoader(Activity activity) { 
     mActivity = activity; 
    } 

    protected void onPreExecute() { 
     mDialog = new ProgressDialog(mActivity); 
     mDialog.setMessage("Loading..."); 
     mDialog.show(); 
    } 

    protected Void doInBackground(Object... args) { 
     publishProgress("Loading something else.."); 
     return null; 
    } 

    protected void onProgressUpdate(String... msg) { 
     mDialog.setMessage(msg[0]); 
    } 

    protected void onPostExecute(Void result) { 
     mDialog.dismiss(); 
    } 
} 

Еще раз спасибо, Джейсон.

ответ

2

Вы должны использовать Async Task, определить пользовательский Async Task, который получает контекст (this) от первоначальной деятельности. Затем сохраните этот контекст для последующего отклонения диалога. Из вашего метода doInBackground() вы можете позвонить postProgress(int progress), который вызовет onProgressUpdate(), который будет вызываться в async task, этот метод находится в потоке пользовательского интерфейса, поэтому он не будет вызывать ошибки поперечного потока. После doInBackground() завершения метода onComplete() также будет называться в потоке пользовательского интерфейса, это, где вы можете использовать сохраненный контекст и dissmiss диалога (context.dissmissDialog()

+0

Эй Джейсон, это звучит многообещающе.Я постараюсь реализовать это и дать отзыв позже! – janoliver

+0

Я обновил свой первый пост с реализацией вашей идеи. Он не работает должным образом. Не могли бы вы взглянуть на код? – janoliver

+0

работает сейчас, имел некоторые незначительные ошибки при реализации AsynTask. Еще раз спасибо. – janoliver

2

Посмотрите на Handler классе Android. При создании обработчика в onCreate метод вашей деятельности, Runnables, которые направляются в post метод обработчика затем запустить на UI нить вашей деятельности:

Handler h; 
protected void onCreate(Bundle bundle) { 
    h = new Handler; 

    new Thread() { 
    public void run() { 
     // your run code 

     h.post(new Runnable() { /* change dialog here */ }); 
    } 
    }.start(); 

} 

Я не уверен, что это лучший вариант, но стоит попробовать .

+0

Эй, Матиас, вы правы, я мог бы использовать Handler и на самом деле пытаюсь это сделать прямо сейчас. Но задача Async была бы намного полезнее. – janoliver

0

В AsyncTask
Вы должны сделать вам работу, которая требуется время в doInBackground и призывающую намерения, как вещи, что вам нужно сделать после того, как эта задача должна быть в onPostExecute

public class ThreadPreLoader extends AsyncTask<Object, String, Void> { 

    private Activity mActivity; 
    private ProgressDialog mDialog; 

    public ThreadPreLoader(Activity activity) { 
     mActivity = activity; 
    } 

    protected void onPreExecute() { 
     mDialog = new ProgressDialog(mActivity); 
     mDialog.setMessage("Loading..."); 
     mDialog.show(); 
    } 

    protected Void doInBackground(Object... args) { 
     //do more 
     publishProgress("Loading something and reached somewhere.."); 
     //do more 
     publishProgress("Loading something and reached somewhere.."); 
     //do more 
     return null; 
    } 

    protected void onProgressUpdate(String msg) { 
     mDialog.setMessage(msg); 
    } 

    protected void onPostExecute() { 
     Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class); 
    BookmarkActivity.this.startActivity(intent); 

     mDialog.dismiss(); 
    } 
} 
Смежные вопросы