studio onpostexecute obtener datos create asynctask asyncresponse java android android-asynctask

java - onpostexecute - Cómo manejar el valor de retorno de AsyncTask



obtener datos de un asynctask (4)

El problema es que cuando se llama a ejecutar, se devuelve el objeto AsyncTask, pero aún no se obtiene el resultado. El resultado se calcula en segundo plano. El tipo de resultado será finalmente una Cadena (como usted especificó), y se pasará a onPostExecute() .

Debe usar AsyncTask siguiente manera:

public class ApiAccess extends AsyncTask<List<NameValuePair>, Integer, String> { ... private String POST(List<NameValuePair>[] nameValuePairs){ ... return response; } protected void onPreExecute (){ // this is run on the main (UI) thread, before doInBackground starts } protected void onPostExecute (String result){ // this is run on the main (UI) thread, after doInBackground returns } protected String doInBackground(List<NameValuePair>... nameValuePairs) { // run in another, background thread return POST(params); } }

Tenga en cuenta que en su ejemplo no está devolviendo el resultado en doInBackground() , como debería.

Estoy usando la clase AsyncTask con la siguiente firma:

public class ApiAccess extends AsyncTask<List<NameValuePair>, Integer, String> { ... private String POST(List<NameValuePair>[] nameValuePairs){ ... return response; } } protected String doInBackground(List<NameValuePair>... nameValuePairs) { return POST(params); }

Estoy tratando de llamarlo desde otra clase a través de:

ApiAccess apiObj = new ApiAccess (0, "/User"); // String signupResponse = apiObj.execute(nameValuePairs); String serverResponse = apiObj.execute(nameValuePairs); //ERROR

Pero aquí me sale este error:

Type mismatch: cannot convert from AsyncTask<List<NameValuePair>,Integer,String> to String

¿Por qué es eso cuando he especificado String como el tercer parámetro en la línea de extensión de Clase?


Por favor lea AsyncTask . Puede obtener el resultado en el método onPostExecute . No puedes hacer algo como:

String serverResponse = apiObj.execute(nameValuePairs);

Porque es asíncrono.


Puede obtener el resultado llamando al método get () de AsyhncTask en el AsyncTask devuelto, pero lo convertirá de una tarea asíncrona en una tarea sincrónica mientras espera para obtener el resultado.

String serverResponse = apiObj.execute(nameValuePairs).get();

Ya que tiene su AsyncTask en una clase separada, puede crear una clase de interfaz y declararla en el AsyncTask e implementar su nueva clase de interfaz como delegado en la clase de la que desea acceder a los resultados. Una buena guía está aquí: ¿Cómo obtener el resultado de OnPostExecute () para la actividad principal porque AsyncTask es una clase separada? .

Intentaré aplicar el enlace anterior a su contexto.

(IApiAccessResponse)

public interface IApiAccessResponse { void postResult(String asyncresult); }

(ApiAccess)

public class ApiAccess extends AsyncTask<List<NameValuePair>, Integer, String> { ... public IApiAccessResponse delegate=null; protected String doInBackground(List<NameValuePair>... nameValuePairs) { //do all your background manipulation and return a String response return response } @Override protected void onPostExecute(String result) { if(delegate!=null) { delegate.postResult(result); } else { Log.e("ApiAccess", "You have not assigned IApiAccessResponse delegate"); } } }

(Su clase principal, que implementa IApiAccessResponse)

ApiAccess apiObj = new ApiAccess (0, "/User"); //Assign the AsyncTask''s delegate to your class''s context (this links your asynctask and this class together) apiObj.delegate = this; apiObj.execute(nameValuePairs); //ERROR //this method has to be implement so that the results can be called to this class void postResult(String asyncresult){ //This method will get call as soon as your AsyncTask is complete. asyncresult will be your result. }


Yo sugeriría implementar una devolución de llamada del controlador. Pasaría el controlador del fragmento (o de la actividad) a AsyncTask, al que llamará AsyncTask cuando haya finalizado. La AsyncTask también puede devolver un objeto arbitrario.

Aquí hay un ejemplo de AsyncTask, que tengo en su propio archivo (no subclasificado):

public class MyTask extends AsyncTask<Void, String, String> { private static final String TAG = "MyTask"; private Handler mCallersHandler; private Candy mObject1; private Popsicle mObject2; // Return codes public static final int MSG_FINISHED = 1001; public SaveVideoTask(Handler handler, Candy candyCane, Popsicle grapePop ) { this.mCallersHandler = handler; this.mObject1 = candyCane; this.mObject2 = grapePop; } @Override protected String doInBackground(Void... params) { // Do all of the processing that you want to do... // You already have the private fields because of the constructor // so you can use mObject1 and mObject2 Dessert objectToReturn = mObject1 + mObject2; // Tell the handler (usually from the calling thread) that we are finished, // returning an object with the message mCallersHandler.sendMessage( Message.obtain( mCallersHandler, MSG_FINISHED, objectToReturn ) ); return (null); } }

Este ejemplo asume que su AsyncTask necesita un pedazo de caramelo y una paleta. Luego devolverá un postre a tu fragmento.

Puede construir y ejecutar AsyncTask en una línea desde su fragmento con:

( new MyTask( mFragmentHandler, candyCane, grapePop ) ).execute();

Pero, por supuesto, primero deberá configurar el controlador del fragmento (myFragmentHandler). Para hacer esto, su fragmento (o actividad) debe verse como (NOTA el "implementa Handler.Callback"):

public class MyFragment extends Fragment implements Handler.Callback { private Handler mFragmentHandler; private Candy candyCane; private Popsicle grapePop; @Override public void onCreate(Bundle savedInstanceState) { // Standard creation code super.onCreate(savedInstanceState); setRetainInstance(true); // Create a handler for this fragment mFragmentHandler = new Handler(this); // Other stuff... } @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { // Inflate the layout View v = inflater.inflate(R.layout.my_fragment_layout, parent, false ); // The candyCane and grapePop don''t need to be set up here, but // they MUST be set up before the button is pressed. // Here would be a good place to at least initialize them... // Perhaps you have a button in "my_fragment_layout" that triggers the AsyncTask... Button mButton = (Button) v.findViewById(R.id.mButton); mButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { ( new MyTask( mFragmentHandler, candyCane, grapePop ) ).execute(); } }); return v; } @SuppressWarnings("unchecked") @Override public boolean handleMessage(Message msg) { switch (msg.what) { case MyTask.MSG_FINISHED: // Let''s see what we are having for dessert Dessert myDessert = (Dessert) msg.obj; break; } return false; } }

Si utiliza estos fragmentos de código, al presionar un botón se activará la AsyncTask. El fragmento de llamada continuará ejecutándose mientras se procesa la AsyncTask. Luego, cuando finalice la AsyncTask, enviará un mensaje al fragmento que dice que está terminado y pasará un objeto con el mensaje. En este punto, el fragmento verá el mensaje y hará lo que desee.

Nota: Puede haber errores tipográficos. Esto se corta de un código muy grande y complicado.