java - onprogressupdate - Cómo dejar que la tarea Async finalice en Android
oncancelled asynctask android (4)
Estoy trabajando en una aplicación que recupera datos de la red, los almacena en el dispositivo y luego los lee. El problema es que obtengo mis datos en una tarea asíncrona. Y mi aplicación no permite que la tarea finalice antes de intentar mostrar los datos al usuario. He intentado con task.get () pero sin resultado (simplemente se detiene ahí).
Aquí está mi tarea:
public GetOptionsTask(XMLPortalGetOptions request) {
super(request);
}
protected void onCancelled(){
// TODO afficher message pas d''options sur le disque
}
@Override
public void handleError(Transaction transaction) {
// TODO afficher message pas d''options sur le disque
}
@Override
public void handleSuccess(Transaction transaction) {
saveOptions(transaction.getResponse());
request = null;
Log.d(OptionsManager.class.getName(), this.getStatus().toString());
}
Esta tarea es una instancia de mi tarea Async personalizada:
protected BaseXMLTransaction request;
public abstract void handleError(Transaction transaction);
public abstract void handleSuccess(Transaction transaction);
public TransactionTask(BaseXMLTransaction request){
this.request = request;
}
@Override
protected Void doInBackground(Void... params) {
try {
Log.i(TransactionTask.class.getName(), "Doing in background");
SocketHandler.sendTransaction(this, request.getRequest());
} catch (SocketHandlerNotConfiguredException e) {
Log.e(TransactionTask.class.getName(), "SocketHandler''s parameters were not set.");
}
return null;
}
@Override
public void transactionResult(Transaction transaction) {
switch (transaction.getCode()) {
case ERROR:
Log.e(TransactionTask.class.getName(), "ERROR !!!");
handleError(transaction);
break;
case NO_CLIENT:
Log.e(TransactionTask.class.getName(), "No Client Error");
handleError(transaction);
break;
case NO_SERVER:
Log.e(TransactionTask.class.getName(), "No Server Error");
handleError(transaction);
break;
case OLD_VERSION:
Log.e(TransactionTask.class.getName(), "Old Version");
handleError(transaction);
break;
case TIMEOUT:
Log.e(TransactionTask.class.getName(), "Transaction Timeout");
handleError(transaction);
break;
case SUCCESS:
Log.i(TransactionTask.class.getName(), "Transaction Success");
handleSuccess(transaction);
}
}
En serio, no sé qué hacer ... Ejecutar va rápido y obtener no hace nada ya que no estoy devolviendo nada, supongo.
onPostExecute (Resultado), invocado en el hilo de la interfaz de usuario una vez que finaliza el cálculo de fondo. El resultado del cálculo de fondo se pasa a este paso como un parámetro.
@Override
protected void onPostExecute(String result) {
}
Una cosa con esa tarea era que estaba guardando cosas en un singleton. Logré llamar a los métodos utilizando la información de la red guardada en singleton en onResume (). Cuando los hilos terminan, van al inicio y todo funciona bien.
Utilizo una interfaz como delegado para hacer esto. Aquí hay un ejemplo:
En mi actividad principal, tengo un oyente onClick para activar mi llamada asincrónica y un oyente para procesar una vez que se completa la llamada.
private void enableLocationButton(){
locationButton = (Button) findViewById(R.id.locationButton);
locationButton.setEnabled(true);
locationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, selectLocationActivity.class);
intent.putExtra("serverURL",server.getWebServerAddressField());
startActivityForResult(intent, 200);
}
});
}
@Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
if(resultCode == RESULT_OK) {
switch (requestCode){
case 100:
processServerResponse((PmsWebServer) data.getBundleExtra("server").get("server"));
break;
case 200:
processLocationResponse((PmsDataSource)data.getBundleExtra("location").get("location"));
default:processError();
}
}else{
processError();
}
}
En algún lugar de la actividad selectLocation tengo una llamada a la llamada Async y algo para procesar la respuesta, tenga en cuenta que esta clase implementa una interfaz que se utiliza en la llamada Async.
public class selectLocationActivity extends ListActivity implements SoapServiceInterface{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_select);
chosenServer = this.removeURLHeader(getIntent().getStringExtra("serverURL"));
this.retrieveLocationOptionsByServer(chosenServer);
}
private void retrieveLocationOptionsByServer(String server) {
Map<String,Object> parms = new HashMap<String,Object>();
parms.put(WEB_SERVER_NAME,server);
SoapServiceObject service = new SoapServiceObject(Services.SERVICE_DETAILS,parms);
callTheService(service);
}
private void callTheService(SoapServiceObject service){
SoapServiceHelper helper = new SoapServiceHelper();
helper.delegate = thisActivity;
helper.execute(service);
}
@Override
public void serviceCallComplete(SoapObject response){
this.createClickableListOnScreen(response);
}
//...more code...//
}
serviceCallComplete es iniciado por asyncTask. A continuación está el código para esa tarea
public class SoapServiceHelper extends AsyncTask<SoapServiceObject, Void, SoapObject>{
public SoapServiceInterface delegate = null;
private Integer RETRY_COUNT = 0;
private final Integer MAX_RETRY_COUNT = 2;
protected SoapObject doInBackground(SoapServiceObject... args){
SoapServiceObject service = args[0];
try{
service.callTheService();
}catch(Exception e){
System.out.println("An error occurred calling the service/n" + e.getMessage());
}
return service.getResponse();
//return callDateTimeService();
}
protected void onPostExecute(SoapObject result){
delegate.serviceCallComplete((SoapObject)(result.getProperty(0)));
}
}
Y finalmente aquí está la interfaz
public interface SoapServiceInterface {
public void serviceCallComplete(SoapObject response);
}
Sé que estoy mostrando algo en la pantalla directamente desde mi resultado, simplemente sub esa parte con un guardar y leer;)
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
y llámalo así:
new DownloadFilesTask().execute(url1, url2, url3);