java - studio - Usar AsyncTask con pasar un valor
oncancelled asynctask android (1)
Bien, aquí hay un patrón bastante flexible para el uso general del uso de AsyncTask para descargar contenido web y obtener los resultados de él de nuevo en el hilo de la interfaz de usuario.
Paso 1 Defina una interfaz que actuará como un bus de mensajes entre AsyncTask y donde desea los datos.
public interface AsyncResponse<T> {
void onResponse(T response);
}
Paso 2 Cree una extensión genérica de AsyncTask que tomará cualquier URL y devolverá los resultados. Básicamente ya tenías esto, pero hice algunos ajustes. Lo más importante es permitir la configuración de la interfaz de devolución de llamada AsyncResponse.
public class WebDownloadTask extends AsyncTask<String, Void, String> {
private AsyncResponse<String> callback;
// Optional parameters
private String username;
private String password;
// Make a constuctor to store the parameters
public WebDownloadTask(String username, String password) {
this.username = username;
this.password = password;
}
// Don''t forget to call this
public void setCallback(AsyncResponse<String> callback) {
this.callback = callback;
}
@Override
protected String doInBackground(String... params) {
String url = params[0];
return readFromFile(url);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (callback != null) {
callback.onResponse(s);
} else {
Log.w(WebDownloadTask.class.getSimpleName(), "The response was ignored");
}
}
/******* private helper methods *******/
private String streamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
private String readFromFile(String myWebpage) {
String response = null;
HttpURLConnection urlConnection = null;
try {
//Get the url connection
URL url = new URL(myWebpage);
// Unnecessary for general AsyncTask usage
/*
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
*/
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
response = streamToString(inputStream);
inputStream.close();
Log.d("Final String", response);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return response;
}
}
Paso 3
Avanza y usa esa AsyncTask donde quieras.
Aquí hay un ejemplo.
Tenga en cuenta que si no utiliza
setCallback
, no podrá obtener los datos que provienen de AsyncTask.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebDownloadTask task = new WebDownloadTask("username", "password");
task.setCallback(new AsyncResponse<String>() {
@Override
public void onResponse(String response) {
// Handle response here. E.g. parse into a JSON object
// Then put objects into some list, then place into an adapter...
Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
}
});
// Use any URL, this one returns a list of 10 users in JSON
task.execute("http://jsonplaceholder.typicode.com/users");
}
}
He estado trabajando en esto y he llegado a un punto en el que no sé qué hacer. Lo que estoy tratando de hacer es usar una clase para descargar y analizar un archivo en una cadena y luego enviar esa cadena a otra clase para analizar el material JSON. Todas las piezas funcionan bien por sí mismas y he probado todo por separado. Simplemente no sé cómo enviar el valor a los análisis Json para comenzar el análisis.
Entonces esta es mi clase de descarga de archivos.
public class JsonFileDownloader extends AsyncTask<String, Void, String> {
//used to access the website
String username = "admin";
String password = "admin";
public String ret = "";
@Override
protected String doInBackground(String... params) {
Log.d("Params ", params[0].toString());
readFromFile(params[0]);
return ret;
}
private String readFromFile(String myWebpage) {
HttpURLConnection urlConnection = null;
try {
//Get the url connection
URL url = new URL(myWebpage);
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
ret = streamToString(inputStream);
inputStream.close();
Log.d("Final String", ret);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
return ret;
}
}
public static String streamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
public String getJsonData()
{
return ret;
}
}
Esto funciona bien. Lo he probado una y otra vez sin errores. El siguiente es el analizador Json que es así.
public class JSONParser {
JSONObject jsonResponse;
String jsonData;
//Consturctor
public JSONParser()
{
//this.jsonData = jsonData;
// this.OutputData = outPutData;
}
public void parsesData(String promo,
ArrayList<String> pictureHTTP,
ArrayList<String> pathHTTP,
ArrayList<String> labelText) throws IOException {
//Build the Json String
JsonFileDownloader jfd = new JsonFileDownloader();
// jsonData = String.valueOf(jfd.execute(promo));
jfd.execute(promo);
//jfd.getResuts(jsonData);
//jsonData = jfd.ret;
Log.d("JsonData String = " , jsonData);
//Try to parse the data
try
{
Log.d("Jsondata " , jsonData);
//Creaate a new JSONObject ith the name/value mapping from the JSON string
jsonResponse = new JSONObject(jsonData);
//Returns the value mapped by the name if it exists and is a JSONArry
JSONArray jsonMainNode = jsonResponse.optJSONArray("");
//Proccess the JSON node
int lenghtJsonArrar = jsonMainNode.length();
for (int i = 0; i<lenghtJsonArrar; i++)
{
//Get object for each json node
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
//Get the node values
//int song_id = Integer.parseInt(jsonChildNode.optString("song_id").toString());
String picture = jsonChildNode.optString("picture").toString();
String pathName = jsonChildNode.optString("path").toString();
String lableName = jsonChildNode.optString("label".toString());
//Debug Testing code
pictureHTTP.add(picture);
pathHTTP.add(pathName);
labelText.add(lableName);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Ahora sé dónde está ocurriendo el problema. Cuando intento asignar un valor a jsonData, nunca se asigna, por lo que es nulo y el sistema falla. He intentado algunas cosas después de jfd.exicute () pero simplemente no sé cómo obtener el valor de la salida de cadena final en jsonData. Gracias por cualquier ayuda con esto.