I am having a scenario in which I am calling asynctask in onclicklistener of button. In post execute method of asynctask I am adding values in arraylist which I want to return to the method calling asynctask
This is my asynctask
public class FetchtopTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
String getitemcode=params[0];
// Building Parameters
ArrayList<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("ItemCode",getitemcode));
Log.d("request!", "starting");
response = CustomHttpClient.executeHttpPost("http://10.0.2.2/top.php",params1);
String retstring=response.toString();
Log.d(retstring,"stringggggg");
return retstring;
}
catch(Exception io){
msg = "No Network Connection";
}
return null;
}
#Override
protected void onPostExecute(String sJson) {
try {
JSONArray aJson = new JSONArray(sJson);
for(int i=0;i<aJson.length();i++)
{
JSONObject jsonO = aJson.getJSONObject(i);
top1.add(jsonO.getString("MName"));
top2.add(jsonO.getString("Amount"));
top3.add(jsonO.getString("TaxStruct"));
}
}catch(JSONException e){
msg = "Invalid response";
}
}
}
I want to pass top1,top2,top3 arraylists to calling method
please help me to achieve this.
You may use ArrayList of ArrayLists:
ArrayList<ArrayList<String>> tops= new ArrayList<ArrayList<String>>();
tops.add(top1);
tops.add(top2);
tops.add(top3);
and
return tops;
hey Just call AsyncTask in btn Click
and in post execute method
call another method which will use that Array which is created in post Execute.
#Override
protected void onPostExecute(String sJson) {
try {
JSONArray aJson = new JSONArray(sJson);
for(int i=0;i<aJson.length();i++)
{
JSONObject jsonO = aJson.getJSONObject(i);
top1.add(jsonO.getString("MName"));
top2.add(jsonO.getString("Amount"));
top3.add(jsonO.getString("TaxStruct"));
anotherMethod(top);
}
}catch(JSONException e){
msg = "Invalid response";
}
}
Related
protected String doInBackground(String... args) {
String myres = null;
String bot_string = args[0] ;
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("question", bot_string));
JSONObject json = jsonParser.makeHttpRequest(url_pythonwebservice, "GET", params);
// Check your log cat for JSON reponse
Log.d("results: ", json.toString());
try {
myres = json.getString(TAG_BOTRESPONSE);
} catch (JSONException e) {
e.printStackTrace();
}
return myres;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
Toast.makeText(getApplicationContext(),file_url , Toast.LENGTH_LONG).show();
//Get reference to textview above in oncreate method
//bot.setText(file_url);
}
if (file_url == "Navigation"){
Intent i = new Intent(Voice.this, MapsActivity.class);
startActivity(i);
}
Toast is printing.I want to call MapsActivity.class if String file_url == "Navigaion" but this is not working if i put inside the onPostExecute. How can i call MapsActivity.class. This is a voice recognition application.
In Java, you should compare two string as,
if(string1.equals(string2))
{
// code block
}
So, for your example, you should change your code like,
if (file_url.equals("Navigation"))
{
// more code follows
}
I´m trying to populate a listview with a custom adapter. How can I fix the following error:
Type mismatch: cannot convert from JSONObject to JSONArray
I have already changed the params but it didn´t work.
private class JSONParse extends AsyncTask<String, String, JSONArray> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ListResult.this);
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONArray doInBackground(String... args) {
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(url);
return json; // Type mismatch: cannot convert from JSONObject to JSONArray
}
#Override
protected void onPostExecute(JSONArray response) {
pDialog.dismiss();
try {
// Getting JSON Array
for(int i = 0; i < response.length(); i++){
JSONObject obj = response.getJSONObject(i);
Medico medico = new Medico();
medico.setNome(obj.getString("name"));
medico.setSobrenome(obj.getString("sname"));
unid = obj.getString("unidade");
serv = obj.getString("servico");
esp = obj.getString("espec");
if(unidade.getText().toString().equalsIgnoreCase(unid) &&
servico.getText().toString().equalsIgnoreCase(serv) &&
espec.getText().toString().equalsIgnoreCase(esp)){
mList.add(medico);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
if(mList.size() > 0){
listView.setAdapter(adapter);
}else{
empty.setText("No results");
}
adapter.notifyDataSetChanged();
}
}
You are returning as JSONArray in doInBackground.
Replace the return type as JSONObject and handle it accordingly wherever it is used
Your doInBackground is passing an Object ( {} datatype) and your onPostExecute is expecting a Array ( [] datatype). The data type is mismatched.
Depends on the JSON data you are trying to process, may try change the onPostExecute to accept an JSONObject then access each properties of it:
#Override
protected void onPostExecute(JSONObjct response)
{
pDialog.dismiss();
try
{
// Getting JSON Array
for (Map.Entry<String,JsonElement> entry : response.entrySet())
{
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
please help, I've given up on finding a solution
Data json already be in ArrayList, nothing error found but the progressdialog can't stop loading. I'm already put PG.dismis in postExecute but even the Adapter cannot changed.
private static List<DataVoucher> processResponse(String response) {
List<DataVoucher> list = new ArrayList<DataVoucher>();
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray jsonArray = jsonObj.getJSONArray("produk");
Log.d(TAG, "data lengt: " + jsonArray.length());
DataVoucher dataVoucher = null;
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
dataVoucher = new DataVoucher();
dataVoucher.setKode(obj.getString("kode"));
dataVoucher.setHrg(obj.getString("hrg"));
dataVoucher.setNom(obj.getString("nom"));
dataVoucher.setKet(obj.getString("ket"));
list.add(dataVoucher);
listvoucher.add(obj.getString("nom"));
}
} catch (JSONException e) {
Log.d(TAG, e.getMessage());
}
return list;
}
public static String requestDataVoucher(final String operator) {
final String TAG = "SEND JSON";
Thread thread = new Thread() {
public void run() {
Looper.prepare();
JSONObject jsonObjSend = new JSONObject();
try {
jsonObjSend.put("type", "svoc");
jsonObjSend.put("hp", "089631633614");
jsonObjSend.put("opr", operator);
Log.i(TAG, jsonObjSend.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
SendHttpPost(jsonObjSend);
Looper.loop();
}
};
thread.start();
return TAG;
}
private class MainActivityAsync extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("retrieving...");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
String response = requestDataVoucher(pilihOperator
.getSelectedItem().toString());
list = processResponse(response);
return null;
}
#Override
protected void onPostExecute(String result) {
adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_item, listvoucher);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
pilihVoucher.setAdapter(adapter);
adapter.notifyDataSetChanged();
if (!adapter.isEmpty()) {
progressDialog.dismiss();
} // this is annoying
}
}
adapter = new ArrayAdapter(MainActivity.this,
android.R.layout.simple_spinner_item, listvoucher);
I think u mean
adapter = new ArrayAdapter(MainActivity.this,
android.R.layout.simple_spinner_item, list);
Btw just dismiss ur progressDialog at onPostExecute() not checking anything and maybe warn the user if the list is empty so you will evade these problems.
Many issues here
doInBackground is running in a thread, different from the ui thread. You are calling requestDataVoucher which is also creating a new thread, useless in this case.
You are calling processResponse with the String response which is the result of requestDataVoucher. According to your code, response equals "SEND JSON". So JSONObject jsonObj = new JSONObject(response); will trigger an Exception, listvoucher will remain empty, and so will your adapter. Conclusion, adapter is empty, the progressDialog won't disappear.
I can't propose a fix, as SendHttpPost is unknown. But as far as goes my understanding, you should remove the Thread creation from requestDataVoucher and return the JSON String generate by SendHttpPost.
Toast is showed around of 2 times, and Json is returning fine 6 objects.
Idk if its problem of RunOnUiThread (I know that is not good for use in asyntask) or otherthing.
what other way can I use for my variable "mensaje" every time that for put a string in that I can show a Toat, maybe in OnPostExecute.
class asyncMensaje extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String user = params[0];
ArrayList<NameValuePair> envioDato = new ArrayList<NameValuePair>();
envioDato.add(new BasicNameValuePair("rut", user));
JSONArray jdata2 = post.getserverdata(envioDato, URL_connectFechas);
if (jdata2 != null && jdata2.length() > 0) {
JSONObject json_data; // creamos un objeto JSON
for (int i = 0; i < jdata2.length(); i++) {
try {
json_data = jdata2.getJSONObject(i);
mensaje = json_data.getString("mensaje");
Log.e("Info: ", "" + mensaje);
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), mensaje, Toast.LENGTH_LONG).show();
}
});
}
}
return null;
}
protected void onPostExecute(String result) {
}
}
The ideal solution in your case is to use onProgressUpdate together with sequencing of Toasts. Refer to this answer for doing the latter.
class asyncMensaje extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
//....
for (int i = 0; i < jdata2.length(); i++) {
//..
publishProgress(mensaje);
}
}
#Override
protected void onProgressUpdate(String... progress) {
//code for showing Toast
}
}
Use onPostExecute method for processing data after getting from webservice in doInBackground instead of using runOnUiThread in doInBackground which run on different Thread. do it as:
#Override
protected String doInBackground(String... params) {
String user = params[0];
ArrayList<NameValuePair> envioDato = new ArrayList<NameValuePair>();
envioDato.add(new BasicNameValuePair("rut", user));
JSONArray jdata2 = post.getserverdata(envioDato, URL_connectFechas);
return jdata2.toString();
}
#Override
protected void onPostExecute(String result) {
JSONArray jdata2=new JSONArray(result);
// parse JSONArray here and show Toast...
}
So I have this loader class which extends AsyncTask. Then I do new loader().execute(); but I want to use the JSONArray response which my loader class returns how do I do that? Because I need it in several different places? Or should I just move my code to onPostExecute and do everything from there?
public class loader extends AsyncTask<String, Integer, JSONArray> {
ProgressDialog dialog;
protected void onPreExecute() {
dialog = ProgressDialog.show(ChallengeList.this, "", "Laddar...");
dialog.setCancelable(true);
}
#Override
protected JSONArray doInBackground(String... params) {
JSONArray response = null;
HttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost(listURL);
try {
HttpResponse resp = client.execute(httppost);
StatusLine statusLine = resp.getStatusLine();
int statusCode = statusLine.getStatusCode();
Log.i("Statuscode", "statusCode"+statusCode);
if (statusCode == 200) {
final JSONObject json = new JSONObject();
json.put("userID", prefs.id());
response = SendHttp.parseHttp(listURL, json);
}
} catch (JSONException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return response;
}
protected void onPostExecute(JSONArray result) {
dialog.dismiss();
}
}
The method onPostExecute has as parameter the JSONArray you returned from the doInBackground method.
onPostExecute runs on your main (caller) activity's thread, so besides dismissing the dialog in that method, you can process the result array further, pass it safely to other methods, etc:
#Override
protected void onPostExecute(JSONArray result)
{
super.onPostExecute(result);
final Message msg = new Message();
msg.obj = result;
if (youWantToUseHandler)
handler.dispatchMessage(msg);
else
writeJSONArray(result);
}
the handler:
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
final JSONArray result = (JSONArray)msg.obj;
writeJSONArray(result);
};
};
Some other method:
private void writeJSONArray(final JSONArray result)
{
for (int i = 0; i < result.length(); i++)
{
try
{
Log.d("SAMPLE", result.get(i).toString());
}
catch (JSONException e)
{
Log.e("SAMPLE", "error getting result " + i, e);
}
}
}
Since onPostExecute "Runs on the UI thread after doInBackground. The specified result is the value returned by doInBackground or null if the task was cancelled or an exception occured." ~API Docs
You can call any method you've declared in your class, and pass this array as a parameter to it.
After downloading the content web you can use the code below in onPostExecute method:
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONObject jsonObject = new JSONObject(s);
String weatherInfo = jsonObject.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray arr = new JSONArray(weatherInfo);
for (int i=0; i < arr.length(); i++) {
JSONObject jsonPart = arr.getJSONObject(i);
Log.i("main",jsonPart.getString("main"));
Log.i("description",jsonPart.getString("description"));
}
} catch (Exception e) {
e.printStackTrace();
}
}