#android #multithreading #android-asynctask #looper
#Android #многопоточность #android-asynctask #цикл
Вопрос:
Код в нижней части этого сообщения запускается следующей строкой кода.
new MasterClickAsyncTask(main).execute(position);
Приведенная ниже часть кода doInBackground вызывает метод, содержащий цикл for, отсюда и необходимость в Looper.prepare() .
Этот код работает нормально первые несколько раз, когда он вызывается, но затем выдает следующую ошибку:
10-15 22:50:24.752: ОШИБКА / AndroidRuntime(9258): Вызвано: java.lang.RuntimeException: для каждого потока может быть создан только один цикл
Я пытался поместить Looper.getMainLooper().quit(); и несколько других подобных вещей в различные части AsyncTask, но это только привело к немедленному сбою.
Любая помощь?
Код:
import java.io.IOException;
import java.net.MalformedURLException;
import org.json.JSONException;
import android.os.AsyncTask;
import android.os.Looper;
import android.view.View;
public class MasterClickAsyncTask extends AsyncTask<Integer, Void, Void> {
Master selectedMaster;
Main main;
MasterGridView masterGridView;
Integer i;
DiscogProxy discogProxy = new DiscogProxy();
MasterClickAsyncTask(Main main){
this.main = main;
this.masterGridView = main.getMasterGridView();
}
@Override
protected void onPreExecute() {
main.progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Void doInBackground(Integer... params) {
masterGridView.getSelectedView();
Globals.selectedMaster = (Master)(masterGridView).getItemAtPosition(params[0].intValue());
Globals.selectedMaster.getVersionListView().getVersionList().clear();
Looper.prepare();
try {
Globals.selectedMaster.getVersionListView().populateVersionList();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Looper.getMainLooper().quit();
return null;
}
@Override
protected void onPostExecute(Void result) {
main.populateAlbumVersionsView();
main.progressBar.setVisibility(View.GONE);
}
}
Ответ №1:
Цикл не имеет ничего общего с циклами for . Цикл — это часть системы Android, которая управляет потоком пользовательского интерфейса. Есть несколько вещей, которые не будут работать без подготовки цикла, но в целом этого лучше избегать Looper.prepare();
, если в этом нет крайней необходимости. Гораздо лучше использовать async doInBackground
для выполнения обработки данных или других более длительных операций, а затем обновлять пользовательский интерфейс с onPostExecute
помощью and onProgressUpdate
.
Короче говоря, если вы каким-либо образом не используете пользовательский интерфейс, вам не нужно вызывать цикл. Если вам приходится вызывать петлитель, вам, вероятно, потребуется изменить структуру работы ваших фоновых потоков.
Комментарии:
1. И если вы пытаетесь изменить пользовательский интерфейс изнутри своей AsyncTask, вызовите publishProgress из doInBackground, а затем внесите изменения в onProgressUpdate .
2. Я смог извлечь все элементы пользовательского интерфейса из своего метода doInBackground() с минимальными усилиями, и все это работает нормально. Большое вам спасибо за ваш совет!