I have implemented an AsyncTask to get values of a web service and store them into an array, but something I am doing wrong because it says that "Invalid index 0, size is 0". The object "dia" is not well created. Here is my code:
private class GetValue extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
metereologia = new ArrayList<DiaTemperatura>();
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
eventos = jsonObj.getJSONArray("list");
// looping through All Contacts
for (int i = 0; i < eventos.length(); i++) {
JSONObject c = eventos.getJSONObject(i);
JSONObject temp = c.getJSONObject(TAG_TEMP);
String max = temp.getString(TAG_MAX);
String min = temp.getString(TAG_MIN);
String humedad = c.getString(TAG_HUMIDITY);
JSONObject weather = c.getJSONObject(TAG_WEATHER);
//String main = weather.getString(TAG_MAIN);
//String description = weather.getString(TAG_DESCRIPTION);
DiaTemperatura dia= new DiaTemperatura();
dia.setMyText(max);
metereologia.add(dia);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
mitext.setText(metereologia.get(0).getMyText());
}
}
It looks like you must be declaring metereologia outside your AsyncTask, then initialising and populating it in the task. This is not quite the correct way to use it. Your AsyncTask should return the result of its computation. You'll need to declare your task as:
private class GetValue extends AsyncTask<Void, Void, List<DiaTemperatura>> {
...
#Override
protected List<DiaTemperatura> doInBackground(Void... arg0) {
List<DiaTemperatura> metereologia = new ArrayList<DiaTemperatura>();
...
return metereologia;
}
and thus onPostExecute becomes:
#Override
protected void onPostExecute(List<DiaTemperatura> metereologia) {
I think that's right, it's off the top of my head...
Your error must be in the line mitext.setText(metereologia.get(0).getMyText()); Its will go for finding the value at the index 0 in your metereologia which its is not getting.
You can not directly set the value of your whole arraylist in such a way. You need to loop for the value whichever you want to set in your TextView.
There is nothing in the metereologia so when you try to get it with (metereologia.get(0).getMyText(), it results in an error, "Invalid index 0, size is 0".
1) For doing check work -
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
String content = "";
if(metereologia.size() == 0)
{
//a check that your metereologia size is 0.
}
for(int i=0;i<metereologia.size();i++)
content = content + metereologia.get(i).getMyText();
mitext.setText(content);
}
}
2) To get the value right-
More convenient way is to return the object metereologia from background and pass it to postExecute method and then process.This is explained by #dave.c.
protected void onPostExecute(List<DiaTemperatura> metereologia) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView mitext = (TextView) getView().findViewById(R.id.temperatura);
String content = "";
if(metereologia.size() == 0)
{
//a check that your metereologia size is 0.
}
for(int i=0;i<metereologia.size();i++)
content = content + metereologia.get(i).getMyText();
mitext.setText(content);
}
}
Related
Progress dialog should appear before display Alert dialog in Android app . I am using android studio.
Alert dialog content will be from Async task in separate class file. So excuting Progress dialog from async task.
But i am not able to see progress dialog screen before AlertDialog opens.
here is my async task code below.
public class ResidentsPaymentInfoHttpResponse extends AsyncTask<String,
Void, List<paymentInfo>> {
ProgressDialog pDialog;
private Context MSAContext;
public ResidentsPaymentInfoHttpResponse(Context context) {
MSAContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(MSAContext,"Autenticando", "Contactando o
servidor, por favor, aguarde alguns instantes.", true, false);
}
#Override
protected List<UserPaymentInfo> doInBackground(String... params){
String flatNo = params[0];
String urls = "https://script.google.com/macros/s/;"
List<UserPaymentInfo> residentsMonthlyPayments = new ArrayList<>();
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(urls)
.build();
Response responses = null;
try
{
responses = client.newCall(request).execute();
String jsonData = responses.body().string();
JSONObject jobject = new JSONObject(jsonData);
JSONArray jarray = jobject.getJSONArray("ResidentsInfo");
int limit = jarray.length();
for(int i=0;i<limit; i++)
{
JSONObject object = jarray.getJSONObject(i);
if(object.getString("FlatNo").equals(flatNo) &&
object.getString("PaymentStatus").equals("notpaid")) {
UserPaymentInfo residentMaintePayment = new
UserPaymentInfo();
UserInfo residentInfo = new UserInfo();
residentInfo.setUserFlatNo(object.getString("FlatNo"));
residentsMonthlyPayments.add(residentMaintePayment);
}
}
}
catch (IOException e)
{
// e.printStackTrace();
}
pDialog.dismiss();
}
catch (Exception ex)
{
// ex.printStackTrace();
}
return residentsMonthlyPayments;
}
protected void onPostExecute(List<UserPaymentInfo> rusult){
super.onPostExecute(rusult);
pDialog.dismiss();
}
}
Am i missing something???
You should not update UI elements (which belong to main/UI thread) inside doInBackground(). May be removing pDialog.dismiss(); from end lines of doInBackground() change the situation.
Check below link.
How to show progress dialog in Android?
you are not calling show() method on progress dialog. You should do it inside preExecute then dismiss it in postExecute method of async task.
Also as said by VSB you should not update UI elements from doInBackground method.
I want to send 3 strings from doInBackground to onPostExecute.
I managed to fetch the data and I can see them in Logs. Now how to use the data stored in Strings once the doInBackground completed its execution.
Here is my code.
public class MainActivity extends AppCompatActivity {
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String url = "http://example.com/test.php";
// JSON Node names
private static final String tag_info = "info";
private static final String tag_success = "Success";
private static final String tag_message = "message";
private static final String tag_output = "output";
// contacts JSONArray
JSONArray info = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling async task to get json
new fetchInfo().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class fetchInfo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
info = jsonObj.getJSONArray(tag_info);
JSONObject c = info.getJSONObject(0);
// I want to use these 3 strings in onPostExecute
String success = c.getString(tag_success);
String message = c.getString(tag_message);
String output = c.getString(tag_output);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView successView = (TextView) findViewById(R.id.success_field);
successView.setText(success + " " + message + " " + output); // I want to print them here
}
}
}
Use String Array
protected String[] doInBackground(String[]... passing) {
String[] result = new String[3];
result[0]= c.getString(tag_success);
result[1] = c.getString(tag_message);
result[2] = c.getString(tag_output);
return result; //return result
}
protected void onPostExecute(String result[]) {
String a = result[0];
}
Bean class
public class BeanClass{
String message,success,output;
public BeanClass(String message,String success,String output){
this.message = message;
this.success = success;
this.output = output;
}
public String getMessage(){ return message;}
public String getSuccess(){ return success;}
public String getOutput(){ return output;}
}
change your async task to
private class fetchInfo extends AsyncTask<Void, Void, BeanClass> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Bean doInBackground(Void... arg0) {
// Creating service handler class instance
Bean result=null;
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
info = jsonObj.getJSONArray(tag_info);
JSONObject c = info.getJSONObject(0);
// I want to use these 3 strings in onPostExecute
String success = c.getString(tag_success);
String message = c.getString(tag_message);
String output = c.getString(tag_output);
result = new Bean(sucess,message,output);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return result;
}
#Override
protected void onPostExecute(Bean result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
if(result!=null){
TextView successView = (TextView) findViewById(R.id.success_field);
successView.setText(result.getSuccess() + " " + result.getMessage() + " " + result.getOutput()); // I want to print them here
}
}
}
try the simply this....... do not need to pass
public class MainActivity extends AppCompatActivity {
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String url = "http://example.com/test.php";
// JSON Node names
private static final String tag_info = "info";
private static final String tag_success = "Success";
private static final String tag_message = "message";
private static final String tag_output = "output";
// contacts JSONArray
JSONArray info = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling async task to get json
new fetchInfo().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class fetchInfo extends AsyncTask<Void, Void, Void> {
String success = "";
String message = "";
String output = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
info = jsonObj.getJSONArray(tag_info);
JSONObject c = info.getJSONObject(0);
// I want to use these 3 strings in onPostExecute
success = c.getString(tag_success);
message = c.getString(tag_message);
output = c.getString(tag_output);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
TextView successView = (TextView) findViewById(R.id.success_field);
successView.setText(success + " " + message + " " + output); // I want to print them here
Log.e("First Value", success);
Log.e("Second Value", message);
Log.e("Third Value", output);
}
}
}
public class fetchInfo extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(Void... params) {
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
info = jsonObj.getJSONArray(tag_info);
JSONObject c = info.getJSONObject(0);
// I want to use these 3 strings in onPostExecute
String success = c.getString(tag_success);
String message = c.getString(tag_message);
String output = c.getString(tag_output);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return output;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (pDialog.isShowing())
pDialog.dismiss();
TextView successView = (TextView) findViewById(R.id.success_field);
successView.setText(s); // I want to print them here
}
}
Do this while declaring
Public class Do Task extends AsyncTask<Void, Void, String>{
then in doInBackground method
protected String[] doInBackground(String[]... passing) {
return result; //change it to a string from null
}
then in onPostExecute result is your string that you want
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
Let me know if you still face an issue.Mark this up if it helps.
Hi i need to save json data in sqlite. But iam getting following error.
Can't create handler inside thread that has not called
Looper.prepare().
This is my code. It is shwoing database open/database created...
/**
* Async task class to get json by making HTTP call
* */
private class GetDetails extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#SuppressLint("NewApi")
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Create an array to populate the spinner
branchlist = new ArrayList<String>();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
// System.out.println("response"+jsonStr);
if (jsonStr != null) {
try {
// jsonString is a string variable that holds the JSON
JSONArray itemArray=new JSONArray(jsonStr);
for (int i = 0; i < itemArray.length(); i++) {
value=itemArray.getString(i);
Log.e("json", i+"="+value);
dbhelper=new DataBaseHepler(getApplicationContext());
sqLiteDatabase=dbhelper.getWritableDatabase();
dbhelper.addinnformation(value,sqLiteDatabase);
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
dbhelper.close();
branchlist.add(itemArray.getString(i));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ArrayAdapter<String> stringadapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
branchlist);
spinner1.setAdapter(stringadapter);
// spinner1
// .setAdapter(new ArrayAdapter<String>(MainActivity.this,
// android.R.layout.simple_spinner_dropdown_item,
// branchlist));
}
}
This error is due to Toast inside doInBackground(Void... arg0) method:
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
Clearly the Android OS wont let threads other than the main thread change UI elements. Follow this link for more details on this: https://dzone.com/articles/android-%E2%80%93-multithreading-ui
I want to get an url from this link:
"http://graph.facebook.com/10202459285618351/picture?type=large&redirect=false"
it gives result:
{
"data": {
"url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xap1/t1.0- 1/s200x200/10342822_10202261537234765_3194866551853134720_n.jpg",
"is_silhouette": false
}
}
I tried,
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(AccountActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
String jsonStr = sh.makeServiceCall(fbPicURL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
fbRealURL = jsonObj.getString("url");
// Phone node is JSON Object
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
// tmp hashmap for single contact
}
catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
}
}
But returning null and its not crashing..
You have to get the data object first like this:
try {
JSONObject jsonObj = new JSONObject(jsonStr);
fbRealURLObj = jsonObj.getJSONObject("data");
fbRealURL = fbRealURLObj.getString("url");
// Phone node is JSON Object
Toast.makeText(AccountActivity.this, fbRealURL,
Toast.LENGTH_LONG).show();
// tmp hashmap for single contact
}
I have an AsyncTask that connects to a service and with an adapter set the result in a ListView. In the action bar I want to put a button to do the refresh action but the problem is that when I click this button and I call to the service it duplicates the results in the list view.
I have tried:
ListView myList=(ListView)findViewById(R.id.list);
myList.setAdapter(null);
if ((new Utils(this)).isConnected()){
new MyTask().execute();
}
My AsyncTask code:
private class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MyActivity.this);
pDialog.setMessage("searching...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url+id, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONArray jsonObj = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < jsonObj.length(); i++) {
JSONObject c = jsonObj.getJSONObject(i);
String nick = c.getString("nick");
String minuto = c.getString("minuto");
String fecha = c.getString("fecha");
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put("nick", nick);
contact.put("minuto", minuto);
contact.put("fecha", fecha);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
DetallePelicula.this, contactList,
R.layout.list_rowopiniones, new String[] { "nick", "minuto",
"fecha" }, new int[] { R.id.title,
R.id.minuto, R.id.fecha });
ListView myList=(ListView)findViewById(R.id.list);
myList.setAdapter(adapter);
}
}
Somebody can help me? thanks
In your doInBackground, you are adding the new data to an already existing list. This means that, as you've mentioned, the data will duplicate.
Just add contactList.clear() to your onPreExecute method:
#Override
protected void onPreExecute() {
super.onPreExecute();
contactList.clear(); // Add this line
// Showing progress dialog
pDialog = new ProgressDialog(MyActivity.this);
pDialog.setMessage("searching...");
pDialog.setCancelable(false);
pDialog.show();
}