Actualizar la barra de progreso de AsyncTaskLoader?
Al usar un AsyncTaskLoader, ¿cómo actualizaría una barra de progreso mostrando el estado en el momento de su actualización? Normalmente, espera que la devolución de llamada se elimine al terminar, pero ¿cómo ejecutar actualizaciones? ¿Dejaría que el hilo principal (ui) encuesta los datos como se está estableciendo o algo?
Edit: Estoy hablando de AsyncTaskLoader , mire la parte del cargador. Aquí está el enlace a la clase: http://developer.android.com/reference/android/content/AsyncTaskLoader.html
- ¿Cómo mostrar la barra de progreso en cada elemento de vista de lista?
- Android - ¿Qué es un progreso secundario en ProgressBar?
- Barra de progreso de Android en ImageView
- ¿Hay una barra de progreso negra para ser visible en un fondo blanco?
- Progreso personalizado no se puede mostrar a veces
Quiero usarlo porque es el futuro :), sé cómo hacer esto con AsyncTask.
- Mostrar el progreso de la descarga dentro de la actividad con DownloadManager
- Necesito saber cuánto bytes se ha cargado para actualizar una barra de progreso android
- ¿Cómo usar setProgressDrawable () correctamente?
- Descargar imágenes con AsyncTask
- ¿Cómo dar una barra de progreso para la descarga?
- Android progressBar no se muestra
- Barra de progreso de Android en el botón
- Cómo crear una barra de progreso circular en Android que gira sobre ella?
Puede hacerlo con cargadores, pero debe mantener y actualizar una WeakReference en su actividad:
public class LoaderTestActivity extends FragmentActivity implements LoaderCallbacks<Void> { private static final int MAX_COUNT = 100; private ProgressBar progressBar; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_async_task_test); progressBar = (ProgressBar) findViewById(R.id.progressBar1); progressBar.setMax(MAX_COUNT); AsyncTaskCounter.mActivity = new WeakReference<LoaderTestActivity>(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_async_task_test, menu); return true; } public void onStartButtonClick(View v) { startWork(); } void startWork() { getSupportLoaderManager().initLoader(0, (Bundle) null, this); } static class AsyncTaskCounter extends AsyncTaskLoader<Void> { static WeakReference<LoaderTestActivity> mActivity; AsyncTaskCounter(LoaderTestActivity activity) { super(activity); mActivity = new WeakReference<LoaderTestActivity>(activity); } private static final int SLEEP_TIME = 200; @Override public Void loadInBackground() { for (int i = 0; i < MAX_COUNT; i++) { try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { e.printStackTrace(); } Log.d(getClass().getSimpleName(), "Progress value is " + i); Log.d(getClass().getSimpleName(), "getActivity is " + getContext()); Log.d(getClass().getSimpleName(), "this is " + this); final int progress = i; if (mActivity.get() != null) { mActivity.get().runOnUiThread(new Runnable() { @Override public void run() { mActivity.get().progressBar.setProgress(progress); } }); } } return null; } } @Override public Loader<Void> onCreateLoader(int id, Bundle args) { AsyncTaskLoader<Void> asyncTaskLoader = new AsyncTaskCounter(this); asyncTaskLoader.forceLoad(); return asyncTaskLoader; } @Override public void onLoadFinished(Loader<Void> arg0, Void arg1) { } @Override public void onLoaderReset(Loader<Void> arg0) { } }
Usted puede utilizar el manejador, pienso que será más ligero para el sistema que la intención
public class MyFragmentActivity extends FragmentActivity{ private final static int MSGCODE_PROGRESS = 1; private final static int MSGCODE_SIZE = 2; private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { Bundle bundle = msg.getData(); if(null != bundle){ int data = msg.getData().getInt(BUNDLE_PROGRESS); if(msg.what == MSGCODE_SIZE){ mProgressBar.setMax(data); } else if(msg.what == MSGCODE_PROGRESS){ mProgressBar.setProgress(data); } } } }; }
Establecer mHandler a constructor de AsyncTaskLoader y de loadInBackground puede actualizar el progreso
Bundle bundle = new Bundle(); bundle.putInt(BUNDLE_PROGRESS, lenghtOfFile); Message msg = new Message(); msg.setData(bundle); msg.what = MSGCODE_SIZE; mHandler.sendMessage(msg);
Yo transmito una Intención a la Actividad (y es recibida por un BroadcastReceiver). No estoy muy contento con esta solución, pero funciona. El AsynTask publishProgress es realmente más fácil de usar. ¿Encontró alguna otra solución?
Estoy usando esto con mi AsyncTaskLoader
, dentro de loadInBackground
runOnUiThread(new Runnable() { public void run() { //UI code } });
Sin embargo, esto no funciona con un cambio de configuración (como el cambio de orientación). No estoy convencido de que AsyncTaskLoader
es el mejor para usar si necesita actualizar la interfaz de usuario, pero funciona mejor al manejar los cambios de configuración. No sé por qué crearon un AsyncTaskLoader
y un AsyncTask
cada uno con sus propias compensaciones. Sólo frustra y confunde a los desarrolladores. Encima de eso AsyncTaskLoader
tiene muy poca documentación.
Saliendo de la respuesta @ garmax, encontré un sitio que mostraba cómo combinar AsyncTaskLoader
s con Fragments en: http://habrahabr.ru/post/131560/
Está en ruso, pero podría publicar mi implementación más tarde.
EDIT : Aquí hay un enlace al ZIP que contiene esa implementación: http://www.2shared.com/file/VW68yhZ1/SampleTaskProgressDialogFragme.html
Acabo de tener este problema. Utilicé un AtomicInteger estático en mi actividad para almacenar el progreso. El cargador lo actualiza a través de una devolución de llamada y la actividad lo sondea y muestra el progreso.
En el cargador callback onLoadFinished
ocultar mi panel de progreso, lo que hace que el bucle de sondeo para salir.
Normalmente yo evitaría el estado estático, pero creo que en general esto es más simple que las alternativas. En mi caso, tengo un diseño diferente en el paisaje, por lo que estoy más feliz dejando que los cambios de orientación se comporten como normal.
private Handler progressHandler; // init with new Handler(getMainLooper()) private static AtomicInteger progress = new AtomicInteger(0); ... private void beginProgressUiUpdates() { progress.set(0); displayProgress(); progressHandler.postDelayed(pollProgress, PROGRESS_POLL_PERIOD_MILLIS); } private Runnable pollProgress = new Runnable() { public void run() { if (findViewById(R.id.progressPanel).getVisibility() == View.VISIBLE) { displayProgress(); progressHandler.postDelayed(pollProgress, PROGRESS_POLL_PERIOD_MILLIS); } } }; private void displayProgress() { ((ProgressBar)findViewById(R.id.progressBar)).setProgress(progress.get()); }
- Creación de un widget de reloj digital con una fuente personalizada
- Configuración de JAVA_HOME en SDK de Android