studio publishprogress oncancelled example clase cancel asynctask android multithreading android-asynctask android-handler

android - publishprogress - Controlador vs AsyncTask vs Hilo



execute asynctask android (12)

Como el Tutorial sobre el procesamiento en segundo plano de Android con manejadores, AsyncTask y Loaders en el sitio de Vogella lo pone:

La clase Handler puede usarse para registrarse en un hilo y proporciona un canal simple para enviar datos a este hilo.

La clase AsyncTask encapsula la creación de un proceso en segundo plano y la sincronización con el hilo principal. También es compatible con los informes de progreso de las tareas en ejecución.

Y un Thread es básicamente el elemento central del multiproceso que un desarrollador puede usar con la siguiente desventaja:

Si usa subprocesos de Java, debe manejar los siguientes requisitos en su propio código:

  • Sincronización con el hilo principal si devuelve resultados a la interfaz de usuario
  • No predeterminado para cancelar el hilo
  • Sin agrupación de hilos por defecto
  • No predeterminado para manejar cambios de configuración en Android

Y con respecto a AsyncTask , como lo AsyncTask documentation :

AsyncTask permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase permite realizar operaciones en segundo plano y publicar resultados en el subproceso de la interfaz de usuario sin tener que manipular subprocesos y / o controladores.

AsyncTask está diseñado para ser una clase auxiliar en torno a Thread y Handler y no constituye un marco de subprocesamiento genérico. Se recomienda utilizar AsyncTasks para operaciones cortas (como mínimo, unos segundos). Si necesita mantener los subprocesos en ejecución durante largos períodos de tiempo, se recomienda encarecidamente que utilice las diversas API proporcionadas por el paquete java.util.concurrent, como Ejecutor, ThreadPoolExecutor y FutureTask.

Actualización de mayo de 2015: encontré una excelente serie de conferencias sobre este tema.

Esta es la búsqueda de Google: Douglas Schmidt conferencia androide concurrencia y sincronización

Este es el video de la primera conferencia en YouTube.

Todo esto es parte del CS 282 (2013): Programación de sistemas para Android de la Universidad de Vanderbilt . Aquí está la lista de reproducción de YouTube

Douglas Schmidt parece ser un excelente profesor

Importante: si se encuentra en un punto en el que está considerando usar AsyncTask para resolver sus problemas de subprocesos, primero debe revisar ReactiveX/RxAndroid para un patrón de programación posiblemente más apropiado. Un buen recurso para obtener una visión general es Aprender RxJava 2 para Android por ejemplo .

Me confundí un poco acerca de las diferencias entre Handlers , AsyncTask y Threads en Android. He leído bastantes blogs y preguntas aquí en stackoverflow.

Handler son hilos en segundo plano que le permiten comunicarse con la interfaz de usuario. La actualización de una barra de progreso, por ejemplo, debe hacerse a través del Handler . Al usar Handlers, tiene la ventaja de MessagingQueues , por lo tanto, si desea programar mensajes o actualizar múltiples elementos de UI o tiene tareas repetitivas.

AsyncTask son similares, de hecho, utilizan Handler , pero no se ejecutan en el subproceso de la interfaz de usuario, por lo que es bueno para obtener datos, por ejemplo, para obtener servicios web. Más tarde podrás interactuar con la interfaz de usuario.

Sin embargo, el Thread no puede interactuar con la interfaz de usuario, proporciona más subprocesos "básicos" y se pierden todas las abstracciones de AsyncTask .

Sin embargo, me gustaría tener una conexión de socket ejecutada en un servicio. ¿Debería ejecutarse esto en un controlador o un hilo, o incluso en una AsyncTask ? La interacción de la interfaz de usuario no es necesaria en absoluto. ¿Hace una diferencia en términos de rendimiento que uso?

Mientras tanto, la documentation ha sido mejorada en gran medida.


Después de mirar en profundidad, es sencillo.

AsyncTask :

Es una forma sencilla de usar un hilo sin saber nada sobre el modelo de hilo de Java . AsyncTask proporciona varias devoluciones de llamada respectivas al subproceso de trabajo y al subproceso principal.

Use para operaciones de espera pequeñas como las siguientes:

  1. Obtención de algunos datos de servicios web y visualización sobre diseño.
  2. Consulta de base de datos.
  3. Cuando te das cuenta de que la operación en ejecución nunca será anidada.

Handler

Cuando instalamos una aplicación en Android, creará un subproceso para esa aplicación llamada MAIN UI Thread. Todas las actividades se ejecutan dentro de ese hilo. Mediante la regla del modelo de un solo hilo de Android, no podemos acceder a los elementos de la IU (mapa de bits, vista de texto, etc.) directamente para otro hilo definido dentro de esa actividad.

Un controlador le permite comunicarse de nuevo con el hilo de la interfaz de usuario de otro hilo de fondo. Esto es útil en Android ya que Android no permite que otros subprocesos se comuniquen directamente con el subproceso de la interfaz de usuario. El controlador puede enviar y procesar los objetos Message y Runnable asociados con MessageQueue de un subproceso. Cada instancia de Handler está asociada con un solo hilo y la cola de mensajes de ese hilo. Cuando se crea un nuevo controlador, se vincula a la cola de subprocesos / mensajes del subproceso que lo está creando.

Es la mejor opción para:

  1. Te permite hacer colas de mensajes.
  2. Programación de mensajes.

Thread :

Ahora es el momento de hablar de hilo.

El hilo es el padre de AsyncTask y Handler . Ambos utilizan internamente subprocesos, lo que significa que también puede crear su propio modelo de subprocesos como AsyncTask y Handler , pero eso requiere un buen conocimiento de la implementación de subprocesos múltiples de Java .


En mi opinión, los subprocesos no son la forma más eficiente de hacer conexiones de socket, pero proporcionan la mayor funcionalidad en términos de ejecutar subprocesos. Lo digo porque, por experiencia, la ejecución de subprocesos durante mucho tiempo hace que los dispositivos sean muy intensos y requieran muchos recursos. Incluso un while(true) simple while(true) calentará un teléfono en minutos. Si dice que la interacción de la interfaz de usuario no es importante, quizás una AsyncTask sea ​​buena porque están diseñadas para procesos a largo plazo. Esta es solo mi opinión al respecto.

ACTUALIZAR

¡Por favor ignore mi respuesta anterior! Respondí a esta pregunta en 2011, cuando tenía mucha menos experiencia con Android de lo que soy ahora. Mi respuesta anterior es engañosa y se considera incorrecta. Lo dejo ahí porque muchas personas lo comentaron a continuación, corrigiéndome, y aprendí mi lección.

Hay muchas otras respuestas mucho mejores en este hilo, pero al menos me daré una respuesta más adecuada. No hay nada de malo en usar un Thread Java normal; sin embargo, realmente debe tener cuidado con la forma en que lo implementa, ya que hacerlo mal puede requerir un uso intensivo del procesador (el síntoma más notable puede ser el calentamiento de su dispositivo). AsyncTask s son ideales para la mayoría de las tareas que desea ejecutar en segundo plano (ejemplos comunes son E / S de disco, llamadas de red y llamadas de base de datos). Sin embargo, no se debe usar AsyncTask s para procesos particularmente largos que pueden ser necesarios después de que el usuario haya cerrado su aplicación o haya puesto su dispositivo en espera. Yo diría que para la mayoría de los casos, cualquier cosa que no pertenezca al hilo de la interfaz de usuario, puede cuidarse en una AsyncTask .


Se AsyncTask una AsyncTask para realizar algunos cálculos en segundo plano y publicar el resultado en el subproceso de la interfaz de usuario (con actualizaciones de progreso opcionales). Como no le preocupa la interfaz de usuario, entonces un Handler o un Thread parece más apropiado.

Puede generar un Thread fondo y pasar mensajes de vuelta a su subproceso principal utilizando el método de post Controlador.


Si observa el código fuente de AsyncTask and Handler , verá que su código está escrito únicamente en Java. (Por supuesto, hay algunas excepciones, pero ese no es un punto importante).

Así que no hay magia en AsyncTask o Handler . Simplemente hacen su trabajo más fácil como desarrollador.

Por ejemplo: si el Programa A llama al método A (), el método A () podría ejecutarse en un hilo diferente con el Programa A. Puede verificarlo fácilmente usando:

Thread t = Thread.currentThread(); int id = t.getId();

¿Por qué deberías usar un nuevo hilo? Puede google para ello. Muchas muchas razones.

Entonces, ¿cuál es la diferencia entre Thread , AsyncTask y Handler ?

AsyncTask y Handler están escritos en Java (internamente usan un Thread ), por lo que todo lo que puede hacer con Handler o AsyncTask , también puede lograr el uso de un Thread .

¿En qué pueden AsyncTask realmente Handler y AsyncTask ?

La razón más obvia es la comunicación entre el subproceso de la persona que llama y el subproceso de trabajo. ( Subproceso de llamada : un subproceso que llama al subproceso de trabajo para realizar alguna tarea. Un subproceso de llamada no necesariamente tiene que ser el subproceso de la interfaz de usuario). Por supuesto, puede comunicarse entre dos hilos de otras maneras, pero existen muchas desventajas (y peligros) debido a problemas de seguridad de los hilos.

Es por eso que debes usar Handler y AsyncTask . Hacen la mayor parte del trabajo por usted, solo necesita saber qué métodos anular.

La diferencia entre Handler y AsyncTask es: usar AsyncTask cuando el subproceso de la persona que llama es un subproceso de la interfaz de usuario . Esto es lo que dice el documento de Android:

AsyncTask permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase permite realizar operaciones en segundo plano y publicar resultados en el subproceso de la interfaz de usuario sin tener que manipular subprocesos y / o controladores

Quiero enfatizar en dos puntos:

1) Uso sencillo del hilo de la interfaz de usuario (por lo tanto, use cuando el hilo de la persona que llama es hilo de la interfaz de usuario).

2) No es necesario manipular los manipuladores. (significa: puede usar Handler en lugar de AsyncTask, pero AsyncTask es una opción más fácil).

Hay muchas cosas en esta publicación que aún no he dicho, por ejemplo: qué es el hilo de la interfaz de usuario o por qué es más fácil. Debe conocer algún método detrás de cada tipo y utilizarlo, entenderá completamente por qué ..

@: cuando lees el documento de Android, verás:

El controlador le permite enviar y procesar objetos Message y Runnable asociados con MessageQueue de un hilo

Pueden parecer extraños al principio. Simplemente entienda que cada hilo tiene cada cola de mensajes (como una lista de tareas pendientes), y el hilo tomará cada mensaje y lo hará hasta que la cola de mensajes esté vacía (al igual que usted termina su trabajo y se va a la cama). Entonces, cuando Handler comunica, solo le da un mensaje al hilo de la persona que llama y esperará para procesarlo. ¿Complicado? Solo recuerde que Handler puede comunicarse con el hilo de la persona que llama de una manera segura.


Thread

Android es compatible con los hilos de Java estándar. Puede utilizar los subprocesos estándar y las herramientas del paquete " java.util.concurrent " para poner las acciones en segundo plano. La única limitación es que no puede actualizar directamente la IU desde un proceso en segundo plano.

Si necesita actualizar la interfaz de usuario desde una tarea en segundo plano, debe usar algunas clases específicas de Android. Puede usar la clase " android.os.Handler " para esta o la clase " AsyncTask "

Handler

La clase " Handler " puede actualizar la interfaz de usuario. Un identificador proporciona métodos para recibir mensajes y para ejecutar. Para usar un controlador, debe subclasificarlo y anular handleMessage() para procesar mensajes. Para procesar Runable , puedes usar el método post(); Solo necesitas una instancia de un controlador en tu actividad.

Usted puede enviar mensajes a través del método sendMessage(Message msg) o sendEmptyMessage .

documentation

Si tiene una Activity que necesita descargar contenido o realizar operaciones que se pueden realizar en segundo plano, AsyncTask permite mantener una interfaz de usuario receptiva y publicar el progreso de esas operaciones para el usuario.

Para más información puedes echar un vistazo a estos enlaces.

http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/

http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask


AsyncTask está diseñado para realizar una operación de no más de unos pocos segundos en segundo plano (no se recomienda para megabytes de descarga de archivos desde el servidor o la tarea de procesamiento de la CPU, como las operaciones de E / S de archivos). Si necesita ejecutar una operación de ejecución prolongada, se le ha recomendado encarecidamente que use subprocesos nativos java. Java te da varias clases relacionadas con hilos para hacer lo que necesitas. Utilice el Handler para actualizar el subproceso de la interfaz de usuario.


Handler - es un medio de comunicación entre hilos. En Android, se utiliza principalmente para comunicarse con el hilo principal al crear y enviar mensajes a través del controlador.

AsyncTask : se utiliza para realizar aplicaciones de larga ejecución en un hilo de fondo. Con n AsyncTask , puede realizar la operación en un subproceso en segundo plano y obtener el resultado en el subproceso principal de la aplicación.

Thread : es un proceso ligero para lograr la concurrencia y la utilización máxima de la CPU. En Android, puedes usar un hilo para realizar actividades que no toquen la interfaz de usuario de la aplicación


Thread :

Puede utilizar el nuevo Thread para tareas de larga ejecución en segundo plano sin afectar el subproceso de la interfaz de usuario. Desde java Thread, no puedes actualizar UI Thread.

Dado que el Thread normal no es muy útil para la arquitectura de Android, se han introducido clases de ayuda para el subprocesamiento.

Puede encontrar respuestas a sus consultas en la página de documentación de rendimiento de subprocesos .

Handler

Un Handler permite enviar y procesar objetos Message y Runnable asociados con MessageQueue un subproceso. Cada instancia de Handler está asociada con un solo hilo y la cola de mensajes de ese hilo.

Hay dos usos principales para un Handler :

  1. Para programar mensajes y ejecutables para ser ejecutados como algún punto en el futuro;

  2. Para poner en cola una acción que se realizará en un subproceso diferente al suyo.

documentation :

AsyncTask permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase le permite realizar operaciones en segundo plano y publicar resultados en el subproceso de la interfaz de usuario sin tener que manipular subprocesos y / o controladores.

Inconvenientes:

  1. De forma predeterminada, una aplicación empuja todos los objetos AsyncTask que crea en un solo hilo. Por lo tanto, se ejecutan en forma serial y, al igual que con el hilo principal, un paquete de trabajo especialmente largo puede bloquear la cola. Debido a esta razón, use AsyncTask para manejar elementos de trabajo de menos de 5 ms de duración .

  2. AsyncTask objetos AsyncTask también son los infractores más comunes para problemas de referencia implícita. AsyncTask objetos de AsyncTask presentan riesgos relacionados con referencias explícitas.

HandlerThread :

Es posible que necesite un enfoque más tradicional para ejecutar un bloque de trabajo en un subproceso de ejecución más larga (a diferencia de AsyncTask, que debe usarse para una carga de trabajo de 5 ms ), y cierta capacidad para administrar ese flujo de trabajo manualmente. Un subproceso de controlador es efectivamente un subproceso de larga duración que toma el trabajo de una cola y opera en él.

ThreadPoolExecutor :

Esta clase administra la creación de un grupo de hilos, establece sus prioridades y administra cómo se distribuye el trabajo entre esos hilos. A medida que aumenta o disminuye la carga de trabajo, la clase aumenta o destruye más subprocesos para ajustarse a la carga de trabajo.

Si la carga de trabajo es más y solo HandlerThread no es suficiente, puede ir a ThreadPoolExecutor

Sin embargo, me gustaría tener una conexión de socket ejecutada en un servicio. ¿Debería ejecutarse esto en un controlador o un hilo, o incluso en una AsyncTask? La interacción de la interfaz de usuario no es necesaria en absoluto. ¿Hace una diferencia en términos de rendimiento que uso?

Dado que la interacción de la interfaz de usuario no es necesaria, no puede ir a AsyncTask . Los hilos normales no son muy útiles y, por HandlerThread tanto, HandlerThread es la mejor opción. Dado que tiene que mantener la conexión de socket, Handler en el hilo principal no es útil en absoluto. Cree un HandlerThread y obtenga un Handler del HandlerThread de HandlerThread .

HandlerThread handlerThread = new HandlerThread("SocketOperation"); handlerThread.start(); Handler requestHandler = new Handler(handlerThread.getLooper()); requestHandler.post(myRunnable); // where myRunnable is your Runnable object.

Si desea volver a comunicarse con el hilo de la IU, puede usar un controlador más para procesar la respuesta.

final Handler responseHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { //txtView.setText((String) msg.obj); Toast.makeText(MainActivity.this, "Foreground task is completed:"+(String)msg.obj, Toast.LENGTH_LONG) .show(); } };

en tu Runnable , puedes agregar

responseHandler.sendMessage(msg);

Más detalles sobre la implementación se pueden encontrar aquí:

Android: tostadas en un hilo


Permítame intentar responder a la pregunta aquí con un ejemplo :) - MyImageSearch [Consulte amablemente la imagen aquí de la pantalla de actividad principal, que contiene un texto de edición / botón de búsqueda / vista de cuadrícula]

Descripción de MyImageSearch : una vez que el usuario ingrese los detalles en el campo de edición de texto y haga clic en el botón de búsqueda, buscaremos imágenes en Internet a través de los servicios web proporcionados por flickr (solo necesita registrarse allí para obtener una clave / token secreto) - para la búsqueda, enviamos una solicitud HTTP y GET JSON Data en respuesta que contiene las direcciones URL de las imágenes individuales que luego utilizaremos para cargar la vista de cuadrícula.

Mi implementación : en la actividad principal definiré una clase interna que extienda AsyncTask para enviar la Solicitud HTTP en el Método doInBackGround y obtener la Respuesta JSON y actualizar mi ArrayList local de FlickrItems, que voy a usar para actualizar mi GridView a través del adaptador de Flickr. (extiende el Adaptador base) y llame al adapter.notifyDataSetChanged () en el onPostExecute () de AsyncTask para volver a cargar la vista de cuadrícula. Tenga en cuenta que aquí la solicitud HTTP es una llamada de bloqueo debido a que lo he hecho a través de AsyncTask. Y puedo almacenar en caché los elementos en el adaptador para aumentar el rendimiento o almacenarlos en la tarjeta SD. La cuadrícula que voy a inflar en el adaptador de Flickr contiene en mi implementación una barra de progreso y una vista de imagen. A continuación puede encontrar el código de mainActivity que utilicé.

Responda a la pregunta ahora . Entonces, una vez que tengamos los datos JSON para obtener imágenes individuales, podemos implementar la lógica de obtener las imágenes en segundo plano a través de controladores o subprocesos o AsyncTask. Debemos tener en cuenta que, dado que mis imágenes una vez descargadas se deben mostrar en la UI / hilo principal, no podemos simplemente usar hilos, ya que no tienen acceso al contexto. En el adaptador de Flickr, las opciones que podría pensar:

  • Opción 1: crear un LooperThread [se extiende el hilo] - y continuar descargando imágenes secuencialmente en un hilo manteniendo este hilo abierto [looper.loop ()]
  • Opción 2: hacer uso de un grupo de subprocesos y publicar el ejecutable a través de myHandler que contiene referencia a mi ImageView, pero como las vistas en la vista de cuadrícula se reciclan, nuevamente el problema puede surgir cuando la imagen en el índice 4 se muestra en el índice 9 [la descarga puede toma mas tiempo]
  • Opción 3 [Utilicé esto]: haga uso de un grupo de subprocesos y envíe un mensaje a myHandler, que contiene datos relacionados con el índice de ImageView y con ImageView mismo, así que mientras hacemos handleMessage () actualizaremos ImageView solo si currentIndex coincide con el índice de La imagen que intentamos descargar.
  • Opción 4: utilice AsyncTask para descargar las imágenes en segundo plano, pero aquí no tendré acceso a la cantidad de subprocesos que deseo en el grupo de subprocesos y varía según la versión de Android, pero en la Opción 3 puedo tomar una decisión consciente del tamaño del conjunto de subprocesos según la configuración del dispositivo que se esté utilizando.

Aquí el código fuente:

public class MainActivity extends ActionBarActivity { GridView imageGridView; ArrayList<FlickrItem> items = new ArrayList<FlickrItem>(); FlickrAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageGridView = (GridView) findViewById(R.id.gridView1); adapter = new FlickrAdapter(this, items); imageGridView.setAdapter(adapter); } // To avoid a memory leak on configuration change making it a inner class class FlickrDownloader extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { FlickrGetter getter = new FlickrGetter(); ArrayList<FlickrItem> newItems = getter.fetchItems(); // clear the existing array items.clear(); // add the new items to the array items.addAll(newItems); // is this correct ? - Wrong rebuilding the list view and should not be done in background //adapter.notifyDataSetChanged(); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); adapter.notifyDataSetChanged(); } } public void search(View view) { // get the flickr data FlickrDownloader downloader = new FlickrDownloader(); downloader.execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }

Espero que mi respuesta, aunque larga, ayude a comprender algunos de los detalles más finos.


Hilo

Cuando inicia una aplicación, se crea un proceso para ejecutar el código. Para utilizar de manera eficiente los recursos informáticos, se pueden iniciar subprocesos dentro del proceso para que se puedan ejecutar múltiples tareas en ese momento. Por lo tanto, los hilos le permiten crear aplicaciones eficientes utilizando la CPU de manera eficiente sin tiempo de inactividad.

En Android, todos los componentes se ejecutan en un único hilo principal llamado. Las tareas de la cola del sistema Android y las ejecutan una a una en el hilo principal. Cuando se ejecutan tareas de ejecución prolongada, la aplicación deja de responder.

Para evitar esto, puede crear subprocesos de trabajo y ejecutar tareas en segundo plano o de larga ejecución.

Entrenador de animales

Dado que Android utiliza el modelo de un solo subproceso, los componentes de la interfaz de usuario se crean sin hilos, lo que significa que solo el subproceso que creó debe acceder a ellos, lo que significa que el componente de la interfaz de usuario debe actualizarse solo en el subproceso principal. Como el componente de la interfaz de usuario se ejecuta en el hilo principal, las tareas que se ejecutan en las hebras de trabajo no pueden modificar los componentes de la interfaz de usuario. Aquí es donde Handler entra en escena. El manejador con la ayuda de Looper puede conectarse a un nuevo hilo o un hilo existente y ejecutar el código que contiene en el hilo conectado.

El manejador hace posible la comunicación entre subprocesos. Usando Handler, el hilo de fondo puede enviarle resultados y el handler que está conectado al hilo principal puede actualizar los componentes de la interfaz de usuario en el hilo principal.

AsyncTask

AsyncTask provisto por Android usa tanto el hilo como el controlador para facilitar la ejecución de tareas simples en segundo plano y actualizar los resultados del hilo de fondo al hilo principal.

Por favor, vea el hilo de Android, el controlador, asynctask y grupos de hilos para ver ejemplos.


public class RequestHandler { public String sendPostRequest(String requestURL, HashMap<String, String> postDataParams) { URL url; StringBuilder sb = new StringBuilder(); try { url = new URL(requestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(15000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setDoInput(true); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8")); writer.write(getPostDataString(postDataParams)); writer.flush(); writer.close(); os.close(); int responseCode = conn.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); sb = new StringBuilder(); String response; while ((response = br.readLine()) != null){ sb.append(response); } } } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for (Map.Entry<String, String> entry : params.entrySet()) { if (first) first = false; else result.append("&"); result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); } return result.toString(); } }