android progress-bar asynctaskloader

android - ¿Deseas actualizar la barra de progreso de AsyncTaskLoader?



progress-bar (6)

Al usar un AsyncTaskLoader, ¿cómo actualizaría una barra de progreso que muestra el estado a medida que se actualiza? Normalmente, esperas a que se elimine la devolución de llamada cuando hayas terminado, pero ¿cómo se ejecutan las actualizaciones? ¿Permitiría que el hilo principal (ui) sondea los datos a medida que se configuran o algo así?

Edición: estoy hablando de AsyncTaskLoader , mira la parte del cargador. Aquí está el enlace a la clase: http://developer.android.com/reference/android/content/AsyncTaskLoader.html

Quiero usarlo porque es el futuro :), sé cómo hacerlo con AsyncTask.


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 sea ​​el mejor para usar si necesita actualizar la interfaz de usuario, pero funciona mejor cuando se manejan cambios de configuración. No sé por qué crearon tanto un AsyncTaskLoader como una AsyncTask cada uno con sus propias compensaciones. Solo frustra y confunde a los desarrolladores. Además de eso, AsyncTaskLoader tiene muy poca documentación.


Puede hacer eso con los cargadores, pero necesita 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) { } }


Puedes usar el controlador, creo que será más ligero para el sistema que para el intento

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); } } } }; }

Configure mHandler como constructor de AsyncTaskLoader y desde 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);



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. ¿Encontraste alguna otra solución?


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 encuesta y muestra el progreso.

En la devolución de llamada del cargador onLoadFinished , onLoadFinished mi panel de progreso, lo que hace que el bucle de sondeo salga.

Por lo general, evitaría el estado estático, pero en general creo que esto es más simple que las alternativas. En mi caso, tengo un diseño diferente en el paisaje, así que estoy más feliz de dejar que los cambios de orientación se comporten normalmente.

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()); }