2014-10-26 2 views
1

У меня есть приложение для Android с AsyncTask, которое отвечает за загрузку файла из Интернета. Этот AsyncTask выполняется при нажатии на элемент в Listview. Поэтому у меня есть пользовательский адаптер и в OnItemClickListener из Listview, я запускаю загрузку и выполняю AsyncTask.Прогресс Диалог не отображается в AsyncTask

Теперь мой адаптер содержит следующий код для запуска AsyncTask имени FileDownloader:

@Override 
public void onClick(View view) { 
    try { 
     FileDownloader fd = new FileDownloader(activity); 
     // some irrelevant code here 
     String filepath = fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString()).get(); 
    } 
    catch(Exception e) { e.printStackTrace(); } 
} 

активности является частным полем, которое передается адаптеру в конструкторе адаптера:

public GameHistoryAdapter(Activity a, int selectedIndex) { 
    this.activity = a; 
} 

Класс FileDownloader содержит метод OnPreExecute, где я хочу показать диалоговое окно выполнения деятельности:

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

    dialog = new ProgressDialog(activity); 
    dialog.setMessage("Downloading..."); 
    dialog.setIndeterminate(true); 
    dialog.setCancelable(true); 
    dialog.show(); 
} 

Но что бы я ни пытался, диалог не появляется. Когда я создаю диалоговое окно предупреждения в методе OnPostExecute для AsyncTask, откроется диалоговое окно.

@Override 
protected void onPostExecute(String res) 
{ 
    super.onPostExecute(res); 
    dialog.hide(); 

    new AlertDialog.Builder(activity) 
      .setTitle(activity.getString(R.string.save_pdf_title_text)) 
      .setMessage(activity.getString(R.string.save_pdf_text) + PDFFileName) 
      .setPositiveButton(activity.getString(R.string.close_text), null) 
      .setIcon(android.R.drawable.ic_dialog_info) 
      .show(); 
} 

Кто-нибудь знает, почему диалог не появляется в моей деятельности?

+0

диалог инициализации в конструкторе AsyncTask..и в onPreExecute только write dialog.show(); – Meenal

ответ

2

Кто-нибудь знает, почему диалог не появляется в моей деятельности?

Да, следующая строка кода ...

String filepath = fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString()).get(); 

Не EVER использовать get() метод AsyncTask. Он блокирует поток основного/пользовательского интерфейса и делает всю точку избыточного AsyncTask. Другими словами, get() превращает его в синхронный процесс вместо асинхронного.

Тот факт, что вы можете показать диалог в onPostExecute(...), просто потому, что он будет вызываться после того, как был вызван блокирующий вызов get(). Это означает, что поток основного/пользовательского интерфейса больше не будет заморожен (заблокирован), и обновления пользовательского интерфейса могут быть сделаны еще раз.

Удалить get() от вашего вызова execute(...) и вместо того, чтобы просто использовать ...

fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString()); 

... затем в ваш метод onPostExecute(...) установит вам filepath переменную с тем, что она должна быть.

Не знаю, кто добавил метод get() в AsyncTask, но если я когда-нибудь их найду, у меня будут серьезные слова. Он мало или вообще не использует и вызывает у многих людей путаницу.

+0

Отличный ответ! Удаление метода get сделало это для меня. Я не знал, что запрос делает синхронный запрос, так что это объясняет многое. Добавление метода get к AsyncTask действительно странно. – Devos50

+0

@ Devos50: Да, я видел довольно много вопросов, таких как ваш здесь, в Stack Overflow, и я никогда не разрабатывал действительно хорошее применение для метода get(). Мне жаль, что они не осудят его или даже не сделают его устаревшим и вообще не уберут. Во всяком случае, рад помочь. – Squonk

+0

Действительные точки действительно, но у меня много ситуаций, когда 'get()' AsyncTask' является _inevitable_. Например: мне нужно показать 'ProgressDialog' ** _ до тех пор, пока загрузка всей сети не будет завершена _ **, затем отпустите ее и продолжите с обновленным пользовательским интерфейсом. Время загрузки неизвестно, поэтому я не могу использовать вариант 'get (time)'. Проще говоря, UI * должен ждать *, и единственный способ сделать это, похоже, с 'get()'. Существуют ли (более простые) альтернативы? –

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