Intereting Posts
Пример Простой пример Gson.fromJson не работает Соответствующее хранение и отображение моих закладок / истории? Monodroid для android-сервиса Snackbar скрывает плавающее действие при нажатии на кнопку действия на нем Почему VideoView в android занимает слишком много времени для загрузки и воспроизведения видео с http-ссылки? Преобразование Json Array в обычный Java-массив Как выбрать дроид без сжатого шрифта? Android не получает обновления местоположения, когда экран заблокирован Выбираемый селектор не работает в Jelly Bean Идея Intellij, показывающая ошибку: не удалось создать виртуальную машину Java Проверка лицензии на Android прямо на applicationError (…) Android multitouch получает неправильные указатели и / или значения XY Добавление фонового изображения в фоновый формат xml Как вернуться на рынок, когда настраиваемая схема URL-адресов Android не обрабатывается? Компиляция собственного кода Android Studio работает медленно

Дождитесь выполнения AsyncTask с помощью ProgressDialog

У меня есть метод public void writeEntry(Activity ctx, Entry entry) который получает некоторые данные и должен вызывать собственный метод, который занимает больше времени для завершения.
Поэтому я создал AsyncTask, который обрабатывает ProgressDialog и собственный метод. Он отлично работает в своей собственной деятельности, чтобы проверить его, в этом мероприятии я использовал интерфейс обратного вызова и так далее.

В моем случае у меня есть описанный выше метод и вы должны выполнить AsyncTask . Выполнение не может быть в этом методе, потому что оно не останавливает дальнейшее выполнение.
Мне нужно получить результат из собственного метода, прежде чем я смогу продолжить выполнение.
Есть ли возможность дождаться AsyncTask до завершения? Метод wait() не является опцией, потому что поток пользовательского интерфейса тоже будет ждать, и поэтому смысл ProgressDialog будет потерян.

Могу ли я использовать метод runOnUiThread() из заданных параметров или является единственным решением для запуска собственной деятельности ?

Поэтому я постараюсь объяснить, насколько могу

Запустите свой тяжелый процесс внутри AsyncTask, но любой код, который вы хотите выполнить после завершения AsyncTask, поместите его в отдельный публичный метод. Теперь, когда вы закончите свой тяжелый процесс, вызовите этот отдельно созданный метод в onPostExecute() .

Так что код psuuedo будет выглядеть так,

 class main extends Activity { class Something extends AsyncTask<String, Integer, String> { protected void onPreExecute() { // Start your progress bar... } protected String doInBackground(String... params) { // Do your heavy stuff... return null; } protected void onPostExecute(String result) { // close your progress dialog and than call method which has // code you are wishing to execute after AsyncTask. } } } 

Надеюсь, это поможет,

Удачи!

Моим первым решением было использование методов обратного вызова с реализацией интерфейса в примере https://stackoverflow.com/a/6396376/390177 .

После чата в чате Android я слышал, что есть более важное решение.
Вы можете использовать IntentService в сочетании с PendingIntent .
Связь осуществляется с помощью Intent .
Если вы хотите использовать ProgressDialog , для этого вам потребуется собственное действие, которое регистрирует, например, BroadcastReciever, а IntentService отправляет его фактический статус для трансляции.

Но давайте начнем сейчас.
Сначала мы создаем Activity , который содержит ProgressDialog и зарегистрированный BroadcastReceiver . BroadcastReceiver прослушивает сообщения об обновлении и завершении диалога.

Для деятельности нам нужен макет …

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#80000000"> </LinearLayout> 

… и связанный код:

 public class ProgressActivity extends Activity { /** * ProgressDialog which is shown */ private ProgressDialog progessDialog_g; /** * Instance of the BroadcastReceiver */ private BroadcastReceiver receiver_g; /** * Identifier for the different settings of the ProgressDialog */ public static final String PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR = "pbar_horizontal_bar"; public static final String PROGRESS_DIALOG_BOOL_CANCELABLE = "pbar_horizontal_cancelable"; public static final String PROGRESS_DIALOG_STR_MESSAGE = "pbar_message"; public static final String PROGRESS_DIALOG_INT_MAX = "pbar_max_bar"; public static final String PROGRESS_DIALOG_INT_VALUE = "pbar_value"; protected static final int PROGRESS_DIALOG_INT_MAX_VALUE = 100; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.progress); progessDialog_g = new ProgressDialog(this); // Reads and sets the settings for the ProgressDialog Intent i = getIntent(); progessDialog_g.setCancelable(i.getBooleanExtra( PROGRESS_DIALOG_BOOL_CANCELABLE, false)); if (i.getBooleanExtra( PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR, false)) { progessDialog_g.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); } else { progessDialog_g.setProgressStyle(ProgressDialog.STYLE_SPINNER); } progessDialog_g .setMessage(i .getStringExtra(PROGRESS_DIALOG_STR_MESSAGE)); progessDialog_g.setMax(i.getIntExtra( PROGRESS_DIALOG_INT_MAX, 100)); // Create the IntentFilter for the different broadcast messages IntentFilter iFilter = new IntentFilter( ExampleProgressService.PROGRESS_DIALOG_BROADCAST_INIT); iFilter.addAction(ExampleProgressService.PROGRESS_DIALOG_BROADCAST_UPDATE); iFilter.addAction(ExampleProgressService.PROGRESS_DIALOG_BROADCAST_FINISH); // Creates the BroadcastReceiver receiver_g = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent){ Log.d(DefaultPreferences.DEBUG_PREFIX + "ProgressActivity", intent.getAction()); if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_INIT .equals(intent.getAction())) { // Sets the ProgressDialog style if (intent .getBooleanExtra( PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR, false)) { progessDialog_g .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); } else { progessDialog_g .setProgressStyle(ProgressDialog.STYLE_SPINNER); } // Shows the ProgressDialog progessDialog_g.show(); } else if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_UPDATE .equals(intent.getAction())) { // Updates the ProgressDialog int value = intent.getIntExtra( PROGRESS_DIALOG_INT_VALUE, -1); if (value != -1) { progessDialog_g.setProgress(value); } } else if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_FINISH .equals(intent.getAction())) { // Finishs the ProgressDialog progessDialog_g.cancel(); finish(); } } }; // Registers the BroadcastReceiver registerReceiver(receiver_g, iFilter); } @Override protected void onDestroy(){ unregisterReceiver(receiver_g); super.onDestroy(); } } 

Теперь мы хотим использовать Activity , поэтому давайте начнем с его вызова:

 final Intent i = new Intent(parentActivity, <packages>.ProgressActivity); i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_CANCELABLE, cancelable_g); i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR, showProgress_g); i.putExtra(ProgressActivity.PROGRESS_DIALOG_STR_MESSAGE, message_g); i.putExtra(ProgressActivity.PROGRESS_DIALOG_INT_MAX, ProgressActivity.PROGRESS_DIALOG_INT_MAX_VALUE); parentActivity.startActivity(i); 

Таким образом, мы запускаем текущую ProgressActivity, которая ждет различных передач. Но сначала нам нужен IntentService , который отправляет трансляции.
Итак, начнем:

 public class ExampleProgressService extends IntentService { /** * PendingIntent for callback. */ protected PendingIntent pi_g = null; private static final String DEBUG_TAG = "ExampleProgressService"; /** * Message identifier for ProgressDialog init */ public static final String PROGRESS_DIALOG_BROADCAST_INIT = "Dialog.Progress.Init"; /** * Message identifier for ProgressDialog finish */ public static final String PROGRESS_DIALOG_BROADCAST_FINISH = "Dialog.Progress.Finish"; /** * Message identifier for ProgressDialog update */ public static final String PROGRESS_DIALOG_BROADCAST_UPDATE = "Dialog.Progress.Update"; /** * Identifier of the result for intent content */ public static final String PROGRESS_DATA_RESULT = "Result"; /** * Identifier of the result error for intent content */ public static final String PROGRESS_DATA_RESULT_ERROR_MESSAGE = "Result.Error.Message"; /** * Identifier of the result error exception for intent content */ public static final String PROGRESS_DATA_RESULT_ERROR_EXCEPTION = "Result.Error.Exception"; /** * Identifier of the result status for intent content */ public static final String PROGRESS_DATA_RESULT_STATUS_BOOL = "Result.Status.boolean"; /** * Identifier of the pending intent for intent content */ public static final String PROGRESS_DATA_PENDING_RESULT = "PendingResult"; public ExampleProgressService() { super("ExampleProgressService"); } /** * Send the finish message. */ private void closeProgressActivity() { Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_FINISH); sendBroadcast(intent); } /** * Do some magic with the intent content */ private void extractVariablesFromIntentAndPrepare(Intent intent) throws Exception { pi_g = (PendingIntent) intent .getParcelableExtra(PROGRESS_DATA_PENDING_RESULT); if (pi_g == null) { throw new Exception("There is no pending intent!"); } /** * Sends an error message. */ private void failed(Exception e, String message) { Intent i = new Intent(); i.putExtra(PROGRESS_DATA_RESULT_ERROR_EXCEPTION, e); i.putExtra(PROGRESS_DATA_RESULT_ERROR_MESSAGE, message); send(i, false); } /** * Sends the init message. */ private void initProgressActivity() { Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_INIT); intent.putExtra(PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR, multipart_g); sendBroadcast(intent); } /** * (non-Javadoc) * * @see android.app.IntentService#onHandleIntent(android.content.Intent) */ @Override protected void onHandleIntent(Intent intent) { extractVariablesFromIntentAndPrepare(intent); initProgressActivity(); // do your calculation here and implements following code Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_UPDATE); intent.putExtra(PROGRESS_DIALOG_INT_VALUE, progressValue); sendBroadcast(intent); // If you finished, use one of the two methods to send the result or an error success(result); failed(exception, optionalMessage); } /** * Sends the data to the calling Activity */ private void send(Intent resultData, boolean status) { resultData.putExtra(PROGRESS_DATA_RESULT_STATUS_BOOL, status); closeProgressActivity(); try { pi_g.send(this, Activity.RESULT_OK, resultData); } catch (PendingIntent.CanceledException e) { Log.e(DEBUG_TAG, "There is something wrong with the pending intent", e); } } /** * Sends the result message. */ private void success(String result) { Intent i = new Intent(); i.putExtra(PROGRESS_DATA_RESULT, result); send(i, true); } } 

Результат выполнения расчета должен быть доступен в parentActivity , поэтому мы создаем PendingIntent в этом Activity и вызываем IntentService .

 // Some identifier for the call int requestCode = 12345; final Intent sI = new Intent(ExampleProgressService.PROGRESS_SERVICE_ACTION); // Callback sI.putExtra(ExampleProgressService.PROGRESS_DATA_PENDING_RESULT, parentActivity .createPendingResult(requestCode, null, PendingIntent.FLAG_CANCEL_CURRENT)); // Service start parentActivity.startService(sI); 

Для получения результатов мы должны переопределить метод onActivityResult(int requestCode, int resultCode, Intent data) .

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ // Compares the requestCode with the requestCode from above if (requestCode == ...) { if (data.getBooleanExtra(ExampleProgressService.PROGRESS_DATA_RESULT_STATUS_BOOL, false)) { // Calculation was success data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT); } else { // Calculation is failed data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_MESSAGE); ((Exception) data.getSerializableExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_EXCEPTION)); } } } 

Это было волшебство, я надеюсь, это поможет вам.