#android #progress-bar #android-asynctask #listactivity #progressdialog
#Android #индикатор выполнения #android-asynctask #listactivity #progressdialog
Вопрос:
Ну, я создаю приложение, в котором я использую ListActivity для отображения просмотров, содержащих изображения, которые я загружаю из Интернета, а также текстовые просмотры и строки рейтинга. Я добавил AsyncTask для управления этим и установил свой setListAdapter в части onPostExecute (); однако я также хотел, чтобы во время выполнения настройки отображалась панель прогресса (или progressdialog).
Панель действительно появляется на некоторое время в моем эмуляторе, но не тогда, когда я пробую свое приложение на устройстве, и даже в эмуляторе панель зависает, когда работает setListAdapter but…it просто я не понял, как добавить publishProgress в мой ArrayAdapter, поскольку это другой класс. Ах да, я установил макет для ListActivity, и именно туда я поместил ProgressBar, но устройство, я полагаю, делает часть doInBackground довольно быстрой, так что макет даже не отображается.
Это то, что у меня пока есть:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
extras = getIntent().getExtras();
platinumCinema = false;
setContentView(R.layout.simple_list_item_1);
Log.i(TAG,"Control B");
MoviesAsyncTask movieTask = new MoviesAsyncTask();
movieTask.execute();
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title_billboard);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgress = (ProgressBar)findViewById(R.id.progressbar_Horizontal);
mProgress.setVisibility(View.VISIBLE);
Log.i(TAG, "PreExecute");
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result.equals("ok"))
Log.i(TAG,"Ended succesfully");
//ProgressDialog mDialog = ProgressDialog.show(BillboardMovieList.this, "","Loading. Please wait...", true);
publishProgress(75);
if(searchMethod.equals("byCinema")){
setListAdapter(new ArrayAdapterSchemaCinemas(BillboardMovieList.this, listMovies,listPosters, listRating, listTimes));
}else
...
Ответ №1:
Не вызывайте publishProgress()
из onPostExecute()
. Для начала, прогресс не изменится до onPostExecute()
завершения, в любом случае, поскольку onProgressUpdate()
необходимо вызвать основной поток приложения, который находится в середине выполнения вашей onPostExecute()
логики.
Если вы все еще чувствуете, что все работает слишком медленно, я бы рекомендовал вам, возможно, использовать Traceview или простые инструкции ведения журнала, чтобы точно определить, в чем проблема.
Комментарии:
1. Пока проблема заключается в настройке ListAdapter, поскольку при генерации этой задачи (если я не ошибаюсь) блокируется поток пользовательского интерфейса для генерации самого списка. Это должно быть сделано в onPostExecute, верно? Потому что doInBackground не может справиться с этим, или может?
2. @Paulina D.: Вы можете создать адаптер в
doInBackground()
, но вы не сможете вызвать егоsetListAdapter()
доonPostExecute()
.3. Как я могу тогда только создать адаптер? В документации ListView я не вижу onCreateAdapter или чего-то подобного = (
4. @Paulina D.: AFAICT, вы уже создаете адаптер. Я вижу
new ArrayAdapterSchemaCinemas
правильно в вашем коде. Учитывая имя класса и то, что оно передаетсяsetListAdapter()
, я предполагаю, что это адаптер.5. Мм … ну, на самом деле я просто переместил фрагмент кода, в котором я извлекал изображения из Интернета (которые я закодировал в ArrayAdapterSchema getView), и это делало все это очень медленным. Итак, усвоенный урок: все «тяжелое» обязательно должно входить в базовую часть doInBackground.