In the application that I'm building, I have to load some datas from a database.
I load the datas when the user select an item from an alert dialog.
I use an AsyncTask class to connect to the database. Here's the code:
public class GetTask extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... arg0) {
getProdotti();
return null;
}
#Override
protected void onPostExecute(Void result) {
pg.dismiss();
for(int w=0;w<all_id.length;w++){
_id.add(all_id[w]);
nomi.add(all_names[w]);
foto.add(all_images[w]);
prezzi.add(all_prices[w]);
descr.add(all_desc[w]);
}
lista = (ListView)findViewById(R.id.lista_prodotti);
ListViewAdapter lva = new ListViewAdapter(nomi , foto , prezzi , _id , descr , context);
lista.setAdapter(lva);
}
protected void onPreExecute(Void result) {
pg = ProgressDialog.show(context, "", "Caricamento in corso...");
}
#Override
protected void onProgressUpdate(Void... values) {
}
}/**/
And i call it so
GetTask cat = new GetTask();
cat.execute();
The progress dialog is shown, but it doesn't disappear and the ListView is not populated.
What i'm doing wrong?
Here's getProdotti():
private void getProdotti(){
try{
httpclient = new DefaultHttpClient();
httppost = new HttpPost(host_url);
datas = new ArrayList<NameValuePair>(1);
datas.add(new BasicNameValuePair("categoria",selected));
Log.d("INVIO",selected);
httppost.setEntity(new UrlEncodedFormEntity(datas));
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
}catch (Exception e){
Toast.makeText(Catalogo.this, "error"+e.toString(), Toast.LENGTH_LONG).show();
}
if(inputStream != null){
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
inputStream.close();
result = sb.toString();
Log.d("RESULT",result);
}catch(Exception e){
Log.e("TEST", "Errore nel convertire il risultato "+e.toString());
}
try{
JSONArray jArray = new JSONArray(result);
all_id = new String[jArray.length()];
all_names = new String[jArray.length()];
all_prices = new String[jArray.length()];
all_images = new String[jArray.length()];
all_desc = new String[jArray.length()];
for(int i=0;i<jArray.length();i++){
JSONObject json_prod = jArray.getJSONObject(i);
Log.d("Debug",json_prod.getString("id_prodotto")+"--"+json_prod.getString("nome_prodotto"));
all_id[i]=json_prod.getString("id_prodotto");
all_names[i]=json_prod.getString("nome_prodotto");
all_prices[i]=json_prod.getString("prezzo");
all_images[i]=json_prod.getString("foto_prodotto");
all_desc[i]=json_prod.getString("descrizione");
}
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
}
Try adding lva.notifyDataSetChanged() inside onPostExecute like this :
lista = (ListView)findViewById(R.id.lista_prodotti);
ListViewAdapter lva = new ListViewAdapter(nomi , foto , prezzi , _id , descr , context);
lista.setAdapter(lva);
lva.notifyDataSetChanged();
Hope this helps, good luck ^^
Actually you have to tell the progress bar to disappear
you have tow ways
first
after setting the adapter to the list call
#Override
protected void onPostExecute(Void result) {
.....
pg.dismiss();
Or you can use handler
define a hanlder such
Handler handler = new Handler (){
#Override
protected void handleMessage(int what){
if(pg.isShowing()){
pg.dismiss();
}
}
}
And in onPostExecute method call
handler.sendEmptyMessage(0);
this will help !!!
Related
I have a listview populated by the data from mysql database. It works fine but when I select an item then press back , the previous listview fecth again data from database that duplicates the items in my listview.
Here's is my code :
public class CityPage extends Activity{
Activity context;
HttpPost httppost;
StringBuffer buffer;
HttpResponse response;
HttpClient httpclient;
ProgressDialog pd;
CityAdapter cityAdapter;
ListView listCity;
ArrayList<City> records;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_page);
context = this;
records = new ArrayList<City>();
listCity = (ListView) findViewById(R.id.cities);
cityAdapter = new CityAdapter(context, R.layout.city_layout, R.id.city_name, records);
listCity.setAdapter(cityAdapter);
listCity.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent myIntent = new Intent(view.getContext(),City_attractions.class);
Toast.makeText(CityPage.this, "Opening", Toast.LENGTH_LONG).show();
String info1 = records.get(position).getCityName();
String info2 = records.get(position).getDescription();
myIntent.putExtra("info1", info1);
myIntent.putExtra("info2", info2);
startActivity(myIntent);
}
});
}
#Override
protected void onStart() {
super.onStart();
fetchCity fetch = new fetchCity();
fetch.execute();
}
private class fetchCity extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(Void... params) {
InputStream is = null;
String result = "";
try {
httpclient = new DefaultHttpClient();
httppost = new HttpPost("http://iguideph-001-site1.btempurl.com/getcity.php");
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
// Get our response as a String.
is = entity.getContent();
} catch (Exception e) {
if (pd != null)
pd.dismiss(); //close the dialog if error occurs
Log.e("ERROR", e.getMessage());
}
//convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("ERROR", "Error converting result " + e.toString());
}
//parse json data
try {
// Remove unexpected characters that might be added to beginning of the string
result = result.substring(result.indexOf(""));
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
City p = new City();
p.setCityName(json_data.getString("place_name"));
p.setDescription(json_data.getString("description"));
records.add(p);
}
} catch (Exception e) {
Log.e("ERROR", "Error pasting data " + e.toString());
}
return null;
}
protected void onPostExecute(Void result) {
if (pd != null) pd.dismiss(); //close dialog
Log.e("size", records.size() + "");
cityAdapter.notifyDataSetChanged(); //notify the ListView to get new records
}
}
}
try remove those lines from onstart() and put them inside oncreate() function
fetchCity fetch = new fetchCity();
fetch.execute();
Good luck !
I have an issue, which is not that big, but to the user it is bad.
The app basically gets the user's input of some place and, when the user clicks on the button, a URL to the Google API with the place on its parameter is sent to an AsyncTask, where it sends this URL via HttpGet and is returned a JSONArray with everything needed. The problem is, when I click on the button and the internet is not that good, the button seems to "freeze" like this:
My activity code is below:
public class MainActivity extends Activity{
...
protected void onCreate(Bundle savedInstanceState){...}
public void onResume()}
btnSearch.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
String search = txtSearch.getText().toString();
try{
List<Location> locations = new SearchTask(MainActivity.this).execute(strSearch).get();
if(locations != null){
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(MainActivity.this, android.R.layout.simple_list_item_1, locations);
listView.setAdapter(adapter);
...
}
}
}
}
}
}
My AsyncTask class code is below:
public class SearchTask extends AsyncTask<String, Void, List<Location>>{
...
protected List<Location> doInBackground(String... params){
if(isNetworkAvailable()){
HttpGet httpGet = null;
HttpClient client = null;
HttpResponse response = null;
StringBuilder builder = null;
try{
String param = URLDecoder.decode(params[0], "UTF-8").replace(" ", "%20");
httpGet = new HttpGet("http://maps.googleapis.com/maps/api/geocode/json?address=" + param + "&sensor=false");
client = new DefaultHttpClient();
builder = new StringBuilder();
}
catch(UnsupportedEncodingException e){
Log.i("Error", e.getMessage());
}
try{
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
int val;
while((val = br.read()) != -1){
builder.append((char) val);
}
}
catch(IOException e){
Log.i("Error", e.getMessage());
}
JSONObject jsonObject = new JSONObject();
List<Location> listLocation = new ArrayList<Location>();
int countJson = 0;
try{
jsonObject = new JSONObject(builder.toString());
JSONArray jArray = jsonObject.getJSONArray("results");
countJson = jArray.length();
for(int i = 0; i < countJson; i++){
Location location = new Location();
String formattedAddress = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getString("formatted_address");
double lat = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
double lng = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
location.setFormattedAddress(formattedAddress);
location.setLat(lat);
location.setLng(lng);
listLocation.add(location);
}
}
catch(JSONException e){
Log.i("Error", e.getMessage());
}
return listLocation;
}
else{
return null;
}
}
#Override
protected void onPreExecute(){
super.onPreExecute();
progress = new ProgressDialog(context);
progress.setMessage("Loading...");
progress.show();
}
#Override
protected void onPostExecute(List<Location> result){
super.onPostExecute();
progress.dismiss();
}
private boolean isNetworkAvailable(){
ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connManager.getActiveNetworkInfo();
return info != null && info.isConnected();
}
}
The ListView is on the same xml of the EditView and the Button.
Is there a way to improve it in order to make the UI not behave like this?
Thanks!
Try this:
btnSearch.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
String search = txtSearch.getText().toString();
new SearchTask(MainActivity.this).execute(strSearch);
}
}
#Override
protected void onPostExecute(List<Location> locations){
if(locations != null){
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(MainActivity.this, android.R.layout.simple_list_item_1, locations);
listView.setAdapter(adapter);
}
progress.dismiss();
}
I am successfully retrieving but unable to put data into listview. how to update ui thread
after retrieving data.
here is the class of asynctask that retrieves data
I tried to update in onPostExecute but couldn't succeed.
class GetJson extends AsyncTask<String, Integer, ArrayList<RowItem>> {
ArrayList<RowItem> rowItems = new ArrayList<RowItem>();
//ArrayList<ArrayList<String>> fullscreens = new ArrayList<ArrayList<String>>() ;
public AsyncResponse delegate = null;
private CustomListViewAdapter arrayadapter;
private ProgressDialog pDialog;
private Context Mycontext;
private ArrayList<String> alist;
private ListView listView;
public GetJson(Context cnxt,ArrayList<String> alist, CustomListViewAdapter adapt,ListView listView) {
Mycontext = cnxt ;
//this.rowItems = rowItems;
this.alist = alist;
this.listView = listView;
}
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
this.pDialog = new ProgressDialog(Mycontext);
this.pDialog.setMessage("Please wait..");
this.pDialog.setIndeterminate(true);
this.pDialog.setCancelable(false);
this.pDialog.show();
//alist.add("fifa");
}
#Override
protected ArrayList<RowItem> doInBackground(String... passing) {
here i am recieving data
return rowItems;
}
#Override
protected void onPostExecute(ArrayList<RowItem> Items) {
super.onPostExecute(Items);
this.pDialog.dismiss();
}
}
I laso tried runuithread in doinBackgroung method
there also i am getting runtime errors
here is my code
protected Void doInBackground(Void... unused) {
runOnUiThread(new Runnable() {
public void run() {
String result = null;
InputStream is = null;
JSONObject json_data=null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
JSONArray ja = new JSONArray();
List<NameValuePair> params = new LinkedList<NameValuePair>();
for(String s : alist)
{
Log.d("s",s);
params.add(new BasicNameValuePair("list[]",s));
}
try{
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
// 2. make POST request to the given URL
HttpGet httpPost = new HttpGet("http://10.0.3.2/infogamma/getapps.php?"+paramString);
// 4. convert JSONObject to JSON to String
String json = ja.toString();
HttpResponse response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
//String json = EntityUtils.toString();
is = entity.getContent();
// Log.d("response", ");
}
catch(Exception e){
Log.i("taghttppost",""+e.toString());
}
//parse response
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder stringbuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringbuilder.append(line + "\n");
}
is.close();
result = stringbuilder.toString();
Log.d("ans",result);
}
catch(Exception e)
{
Log.i("tagconvertstr",""+e.toString());
}
//get json data
try{
//JSONObject json = new JSONObject(result);
JSONArray jArray = new JSONArray(result);
Log.d("app_lentgh", Integer.toString(jArray.length()));
for(int i=0;i<jArray.length();i++)
{
json_data = jArray.getJSONObject(i);
// this.donnees.add("title: "+ json_data.getString("title") + " appid: " + json_data.getString("appid") );
try{
//commmand http
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://10.0.3.2/infogamma/getAppDetails.php?appid="+json_data.getString("appid"));
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
//String json = EntityUtils.toString();
is = entity.getContent();
// Log.d("response", ");
}
catch(Exception e){
Log.i("taghttppost",""+e.toString());
}
//parse response
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.d("ans",result);
}
catch(Exception e)
{
Log.i("tagconvertstr",""+e.toString());
}
ArrayList<String> screenitem = new ArrayList<String>();
try{
JSONObject j = new JSONObject(result);
screenitem.add(j.getString("scr1"));
screenitem.add(j.getString("scr2"));
screenitem.add(j.getString("scr3"));
// this.fullscreens.add(screenitem);
// RowItem(ImageView imageId, String title, String desc,String catgs,String downloads,String rating,String discription)
RowItem item = new RowItem(j.getString("coverimage"), j.getString("title"), j.getString("category"),j.getString("downloads"),j.getString("rating"),
j.getString("scr1"),j.getString("scr2"),j.getString("scr3"),j.getString("discription"),j.getString("developer"),j.getString("price")
,json_data.getString("appid"));
rowItems.add(item);
}
catch(JSONException e){
Log.i("tagjsonexp",""+e.toString());
}
//SharedPreferences.Editor editor = ((Activity) Mycontext).getPreferences(Mycontext.MODE_PRIVATE).edit();
//editor.;
//editor.commit();
//Log.i("title",json_data.getString("title"));
}
}
catch(JSONException e){
Log.i("tagjsonexp",""+e.toString());
} catch (ParseException e) {
Log.i("tagjsonpars",""+e.toString());
}
adapt = new CustomListViewAdapter(getApplicationContext(),
R.layout.list_item, rowItems);
listView.setAdapter(adapt);
}});
return (null);
}
You can populate the list view from doInBackground by this code
runOnUiThread(new Runnable() {
public void run() {
//set listview Adapter here
}
});
this thing is not preferable. One more thing you can do is create a class which can hold the data you want to show on the item of a list and pass the array of that class object to onPostExecute method from where you can handle the UI thread.
Do it in onPostExecute() or if you want to add them from doInBackground() instantly, do it using runOnUiThread().
Edit:
After reading your comments, You are using CustomListViewAdapter, do you have a constructor with Context,int,ArrayList<String> as parameters in your adapter class?
I want to show huge data (+50,000 records) in android listview using Async.
The data comes from web services(dot net) in pages(1000 records in each page).
As I get 1000 records I have to update the listview automatically (without scrolling).This process continues till all the records are fetched.
Am able to fetch all the records but unable to update listview.
My code is :
class XYZ extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... params) {
for(int i=1;i<=noOfPagesFromServer;i++)
{
String url="http://182.72.123.138:9523/Service.svc/GetData/"+i;
try
{
HttpGet get =new HttpGet(url );
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(get);
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
stringBuilder.append(line + "\n");
}
String responseString = stringBuilder.toString();
JSONObject serverJSONObj = new JSONObject(responseString);
JSONArray serverJSONArray = serverJSONObj .getJSONArray("ABC");
for(int l=0;l<serverJSONArray.length();l++)
{
JSONObject tempJSONObject=serverJSONArray.getJSONObject(l);
a = tempJSONObject.getString("A");
b =tempJSONObject.getString("B");
Model model=new Model(a,b);
arrayList.add(model);}
} catch (Exception e) {
e.printStackTrace();
}
publishProgress(null);
SystemClock.sleep(6000);
}return null;}
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
adapter1 = new CustomListViewAdapter(SearchActivity.this,R.layout.row,arrayList);
listView.setAdapter(adapter1);
listView.this.adapter1.notifyDataSetChanged();
}
#Override
protected void onPostExecute(String result) {
try{
super.onPostExecute(result);
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter1 = new CustomListViewAdapter(SearchActivity.this,R.layout.row,arrayList);
adapter1.notifyDataSetChanged();
listView.setAdapter(adapter1);
}
});
}
catch(Exception e){
e.printStackTrace();
}
}
Thanks for your replies
You can use onProgressUpdate() and acheive the required result...update your model once you receive the 1000 records and update the list...
I was using the code from the doInBackground section to load a custom listview from a database and now that I have added it to an AsynchTask it shows nothing when the dialog has been dismissed. Does anyone know what I am doing wrong so that it will display my list when the progress bar dismisses again:
private class LoadList extends AsyncTask<String, UserRecord, JSONArray> {
protected JSONArray doInBackground(String... link) {
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://wallpaperapp.x10.mx/new.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection"+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line="0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONArray(result);
JSONObject json_data=null;
displayname = new String[jArray.length()];
song_name = new String[jArray.length()];
artist = new String[jArray.length()];
description = new String[jArray.length()];
genre = new String[jArray.length()];
custom_genre = new String[jArray.length()];
album = new String[jArray.length()];
timestamp = new String[jArray.length()];
song_id = new int[jArray.length()];
avatar = new String[jArray.length()];
drawable = new Drawable[jArray.length()];
test_rating = new Float[jArray.length()];
songurl = new String[jArray.length()];
for(int i=0;i<jArray.length();i++){
json_data = jArray.getJSONObject(i);
song_id[i]=json_data.getInt("id");
song_name[i]=json_data.getString("songname");
artist[i]=json_data.getString("artist");
displayname[i]=json_data.getString("displayname");
description[i]=json_data.getString("description");
genre[i]=json_data.getString("genre");
custom_genre[i]=json_data.getString("customgenre");
album[i]=json_data.getString("album");
timestamp[i]=json_data.getString("format");
avatar[i]=json_data.getString("image_url");
songurl[i]=json_data.getString("song_url");
drawable[i] = LoadImageFromWebOperations(avatar[i]);
test_rating[i] = (float) json_data.getDouble("rating");
user5 = new UserRecord(genre[i], displayname[i], timestamp[i], drawable[i], test_rating[i], songurl[i]);
publishProgress(user5);
}
}
catch(JSONException e1){
Toast.makeText(getBaseContext(), "No results found." ,Toast.LENGTH_LONG).show();
} catch (ParseException e1) {
e1.printStackTrace();
}
return null;
}
protected void onProgressUpdate(UserRecord... progress) {
users.add(user5);
}
protected void onPostExecute(JSONArray jArray) {
dialog.dismiss();
}
protected void onPreExecute(){
dialog = ProgressDialog.show(mainmenu.this, "",
"Loading. Please wait...", true);
}
}
Here is my onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsmain);
nameValuePairs = new ArrayList<NameValuePair>();
users = new ArrayList<UserRecord>();
ListView listView = (ListView) findViewById(R.id.ListViewId);
songname = (TextView) findViewById(R.id.tvTrack);
songimage = (ImageView) findViewById (R.id.imageView1);
playbutton = (Button) findViewById (R.id.playbutton1);
downloadbutton = (Button) findViewById (R.id.downloadbutton3);
listView.setAdapter(new UserItemAdapter(this, android.R.layout.simple_list_item_1, users));
flipper = (ViewFlipper) findViewById(R.id.tab2);
//when a view is displayed
flipper.setInAnimation(this,android.R.anim.fade_in);
//when a view disappears
flipper.setOutAnimation(this, android.R.anim.fade_out);
screenWidth = getResources().getDisplayMetrics().widthPixels;
new LoadList().execute();
}
The UserRecord that is getting published:
public class UserRecord {
public String genrez;
public String displaynamez;
public String timestampz;
public Drawable image_urlz;
public Float test_ratingz;
public String songurlz;
public UserRecord(String genrez, String displaynamez, String timestampz, Drawable image_urlz, Float test_rating, String songurlz) {
this.genrez = genrez;
this.displaynamez = displaynamez;
this.timestampz = timestampz;
this.image_urlz = image_urlz;
this.test_ratingz = test_rating;
this.songurlz = songurlz;
}
}
Adding this to my onPostExecute worked! I am so happy I figured it out.. thanks
listView.setAdapter(new UserItemAdapter(mainmenu.this, android.R.layout.simple_list_item_1, users));
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
}
please put listview code in this function, means binding data to listview