2012-04-07 4 views
0

Я пытаюсь извлечь данные из Интернета, проанализировать его и затем показать данные пользователю. Действие обычно занимает 3 секунды или около того, и я хотел бы, чтобы spinner ProgressDialog показывал сообщение о том, что я загружаю данные. Проблема в том, что ProgressDialog появляется только тогда, когда загрузка почти завершена. Это мой кодProgressDialog не отображается сразу

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button load_routes = (Button)findViewById(R.id.load_routes); 

    load_routes.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      task_complete = false; 
      progressBar = new ProgressDialog(v.getContext()); 
      progressBar.setCancelable(false); 
      progressBar.setMessage("Fetching routes data ..."); 
      progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
      progressBar.show(); 

      if(haveNetworkConnection()) 
      { 
       loading_routes_data(v); 
      } 
      else 
      { 
       progressBar.dismiss(); 
      } 
     } 
    }); 
} 

И это моя функция, которая вызывается OnClick

private void loading_routes_data(View v) 
{ 
    try 
    { 
     new Thread(new Runnable() 
     { 
      public void run() 
      { 
       while(!task_complete) 
       { 
        refresh_routes(); 
        try 
        { 
         Thread.sleep(1000); 
        } 
        catch(InterruptedException e) 
        { 
         e.printStackTrace(); 
        } 
       } 
       runOnUiThread(new Runnable() 
       { 
        public void run() 
        { 
         progressBar.dismiss(); 
        } 
       }); 
      } 
     }).start(); 
    } 
    catch(Exception e) 
    { 
    } 

    while(!task_complete) 
    { 
    } 
} 

Моя refresh_routes() функция получает данные, обрабатывает его, а затем устанавливает task_complete в true, я даже не уверен в том или нет, я должен держать его внутри цикла while.

Так что это моя огромная проблема. Я хотел бы сразу показать ProgressDialog нажатием кнопки, тогда я бы хотел позвонить refresh_routes(), и как только refresh_routes() будет завершен, я хотел бы избавиться от диалога прогресса. Но я не уверен, как это сделать.

Если кто-то может показать мне, как решить проблему с какой-либо статьей в качестве примера или что-то в этом роде, я буду очень благодарен. Заранее спасибо :)

ответ

2

Вы блокируете поток пользовательского интерфейса, вызывая while(!task_complete) в конце вашего метода. Вы действительно должны использовать AsyncTask для такой операции. Вот что ваш AsyncTask должен выглядеть следующим образом:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { 

    private ProgressDialog progressDialog; 
    private Context context; 

    public MyAsyncTask(Context context) { 

     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 
     progressDialog = ProgressDialog.show(context, null, "Fetching routes data ..."); 
    } 

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

     while (!task_complete) { 
      refresh_routes(); 
      try { 
       Thread.sleep(1000); 
      } 
      catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     super.onPostExecute(result); 
     progressDialog.dismiss(); 
    } 
} 

Чтобы выполнить это, вы могли бы сделать это:

new MyAsyncTask(this).execute(); 

Я не уверен, как работает ваш метод refresh_routes(), но вы могли бы рассмотреть вопрос о переносе его функциональность внутри метод doInBackground().

+0

Удивительно, это сработало! Все учебники онлайн говорят использовать Threads, но это просто потрясающе. Также вы узнали бы, есть ли способ, которым я могу вызвать функцию, которая принимает представление как параметр из asynch? – Quillion

+0

Если вам нужно показать прогресс во время работы фонового процесса, переопределите метод onProgressUpdate (...) '. Затем, чтобы вызвать действие, вы можете вызвать 'publishProgress (...)' из метода 'doInBackground()'. Он будет автоматически запускаться в потоке пользовательского интерфейса. Пожалуйста, прочитайте документацию по «AsyncTask», чтобы понять, как все сочетается. –

1

Используйте AsyncTask для этого. Это дает вам отличную возможность выполнять многопоточность с помощью Activity.

Смежные вопросы