I have such JSONparser class:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
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();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
and such activity:
public class BankExchangersListActivity extends ExpandableListActivity {
private static String url;
// JSON Node names
private static final String TAG_Exchangers = "bank_exchangers";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_address = "address";
private static final String TAG_location_name = "location_name";
private static final String TAG_latitude = "latitude";
private static final String TAG_longitude = "longitude";
private static final String TAG_exchanger_type_name = "exchanger_type_name";
private static final String TAG_exchanger_curr_value = "value";
private static final String TAG_currency_list_name = "currency_list_name";
private static final String TAG_direction_of_exchange_name = "direction_of_exchange_name";
JSONArray banks = null;
JSONArray exc_currencies = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
String bank;
bank = this.getIntent().getStringExtra("Bank_id");
url = "****/**_**_***_list/"+bank+".json";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bank_exchangers_list);
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
ArrayList result = new ArrayList();
try {
// Getting Array of Contacts
banks = json.getJSONArray(TAG_Exchangers);
// looping through All Contacts
for(int i = 0; i < banks.length(); i++){
JSONObject c = banks.getJSONObject(i);
exc_currencies = c.getJSONArray("currency_values");
HashMap<String, String> map2 = new HashMap<String, String>();
ArrayList secList = new ArrayList();
for(int k = 0; k < exc_currencies.length(); k++){
JSONObject m = exc_currencies.getJSONObject(k);
String currency = m.getString(TAG_exchanger_curr_value);
String currency_list_name = m.getString(TAG_currency_list_name);
String direction_of_exchange_name = m.getString(TAG_direction_of_exchange_name);
Log.e("wazzzup", currency); //here is trouble: how to do new array with linking to parent?
HashMap child = new HashMap();
child.put(TAG_exchanger_curr_value, currency );
child.put(TAG_currency_list_name, currency_list_name );
child.put(TAG_direction_of_exchange_name, direction_of_exchange_name );
secList.add(child);
}
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
Log.e("name", name); //here is trouble: how to do new array with linking to parent?
String address = c.getString(TAG_address);
String location_name = c.getString(TAG_location_name);
String latitude = c.getString(TAG_latitude);
String longitude = c.getString(TAG_longitude);
String exchanger_type_name = c.getString(TAG_exchanger_type_name);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_address, address);
map.put(TAG_location_name, location_name);
map.put(TAG_latitude, latitude);
map.put(TAG_longitude, longitude);
map.put(TAG_exchanger_type_name, exchanger_type_name);
// adding HashList to ArrayList
contactList.add(map);
result.add(secList);
}
} catch (JSONException e) {
e.printStackTrace();
}
/*ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.bank_exchanger_list_element,
new String[] { TAG_NAME, TAG_location_name, TAG_address, TAG_exchanger_type_name, TAG_latitude, TAG_longitude }, new int[] {
R.id.bank_e_n, R.id.nas_punkt_e_n , R.id.adress_obm_e_n , R.id.tip_obm_e_n , R.id.shirota_e_n , R.id.dolgota_e_n });
setListAdapter(adapter);*/
SimpleExpandableListAdapter expListAdapter =
new SimpleExpandableListAdapter(
this,
contactList,
R.layout.bank_exchanger_list_element,
new String[] { TAG_NAME, TAG_location_name, TAG_address, TAG_exchanger_type_name, TAG_latitude, TAG_longitude },
new int[] {
R.id.bank_e_n, R.id.nas_punkt_e_n , R.id.adress_obm_e_n , R.id.tip_obm_e_n , R.id.shirota_e_n , R.id.dolgota_e_n },
result, //something goes here
R.layout.exchanger_currencies,
new String[] {TAG_exchanger_curr_value, TAG_currency_list_name, TAG_direction_of_exchange_name},
new int[] { R.id.currencyvalue_e_n, R.id.currency_list_name_e_n, R.id.direction_of_exchange_e_n}
);
setListAdapter( expListAdapter );
ExpandableListView elv = (ExpandableListView) getExpandableListView();
for(int i=0; i < expListAdapter.getGroupCount(); i++)
elv.expandGroup(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bank_exchangers_list, menu);
return true;
}
}
On android 2.3.3 it works properly. But on 4.x i see errors, after searching I understood that I need to use AsyncTask. Is it true?
But how do I use it here? If there are any useful examples, please let me know.
Just how to get it working on Android 4.x?
You should already use AsyncTask under Android 2.x. It greatly improves responsiveness. Here is a fragment from my MEGA API library (currently under development):
private class AsyncRequestConnection extends AsyncTask<Void, Void, String> {
private final Request request;
public AsyncRequestConnection(Request request) {
this.request = request;
}
#Override
protected String doInBackground(Void... params) {
try {
HttpPost p = createRequestHttpMessage(request);
String resp = new String(stripResponse(getRequestClient().execute(p)));
Log.v(TAG, resp);
return resp;
} catch (Exception e) {
Log.e(TAG, "Cannot complete API request", e);
cancel(false);
return null;
}
}
#Override
protected void onCancelled() {
request.backoff();
if (request.hasReachedMaxBackoff()) {
request.cancel(R.string.error_internal);
} else {
requestQueue.enqueue(request);
}
requestConnection = null;
nextRequest();
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
request.attachResponse(result);
request.handleResponse();
requestConnection = null;
nextRequest();
} else {
request.cancel(R.string.error_internal);
}
}
}
doInBackgroud() is the only method that is run on a different thread. Here, all your costly operations should happen.
getRequestClient() returns a HttpClient (AndroidHttpClient.newInstance(AGENT_NAME) or reused object for multiple requests in a row).
Since you are running muliple threads here, make sure doInBackground() does not access any global data structure. In my example, get getRequestClient() is sure to be only called from this location and there is only one such AsyncTask at any time. Otherwise you need some kind of mutex. Also, the Request object is sure to used by this class exlusively. Event handling (call-back methods) is implemented in the Request object as well but for simpler tasks you could simply do everything you want to do in onCancel() and onPostExecute().
If you only want to download a JSON object and parse it, you probably won't even need a constructor and private member variables. Simply replace the first Void by String to pass the URL string to doInBackground() and replace String by JSONObject.
Related
I have been trying to parse json with volley , somehow i managed to extract some data but i am unable parse other fields . What i am trying do is checking which user role is doctor and store only that user to a1 arraylist
{"user1":{"password":"******","presence":{"lastSeen":1484695229773,"status":"online"},"role":"Patient"},"user2":{"password":"******","presence":{"lastSeen":1484695229773,"status":"offline"},"role":"Doctor"}}
here is my code :
public class Users extends AppCompatActivity {
ListView usersList;
TextView noUsersText;
ArrayList<String> al = new ArrayList<>();
int totalUsers = 0;
ProgressDialog pd;
private Firebase mRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_users);
usersList = (ListView)findViewById(R.id.usersList);
noUsersText = (TextView)findViewById(R.id.noUsersText);
pd = new ProgressDialog(Users.this);
pd.setMessage("Loading...");
pd.show();
String url = "https://**********.firebaseio.com/users.json";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
#Override
public void onResponse(String s) {
doOnSuccess(s);
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("" + volleyError);
}
});
RequestQueue rQueue = Volley.newRequestQueue(Users.this);
rQueue.add(request);
usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UserDetails.chatWith = al.get(position);
startActivity(new Intent(Users.this, Chat.class));
}
});
}//oncreate ends here
public void doOnSuccess(String s){
try {
JSONObject obj = new JSONObject(s);
Iterator i = obj.keys();
String key = "";
while(i.hasNext()){
key = i.next().toString();
if(!key.equals(UserDetails.username)) {
al.add(key); /// here want to store only user with doctor role
//currently all users are displaying
}
totalUsers++;
}
} catch (JSONException e) {
e.printStackTrace();
}
if(totalUsers <=1){
noUsersText.setVisibility(View.VISIBLE);
usersList.setVisibility(View.GONE);
}
else{
noUsersText.setVisibility(View.GONE);
usersList.setVisibility(View.VISIBLE);
usersList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, al));
}
pd.dismiss();
}
}
i am successfully getting the Root Object "user1" and "user2" but i want to extract all other fields as well
kindly tell how i have to change my code for all fields.
EDITED
public void doOnSuccess(String s){
try {
JSONObject obj = new JSONObject(s);
Iterator i = obj.keys();
String key = "";
while(i.hasNext()){
key = i.next().toString();
JSONObject singleUser = (JSONObject) obj.get(key);
String role = singleUser.get("role").toString();
if(!key.equals(UserDetails.username)) {
if (role.equals("Doctor")) {
// doctors.add(keys);
al.add(key);
}
}
totalUsers++;
}
} catch (JSONException e) {
e.printStackTrace();
}
if(totalUsers <=1){
noUsersText.setVisibility(View.VISIBLE);
usersList.setVisibility(View.GONE);
}
else{
noUsersText.setVisibility(View.GONE);
usersList.setVisibility(View.VISIBLE);
usersList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, al));
}
pd.dismiss();
}
}
You get the values from the User Object as follows
JSONObject user = obj.getJSONObject("user1");
String role = user.getString("role");
JSONObject presence = user.getJSONObject("presence");
String status = presence.getString("status");
This should give all users with doctor role.
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader(
"sample.json"));
JSONObject jsonObject = (JSONObject) obj;
Set<String> keySet = jsonObject.keySet();
List<String> doctors = new ArrayList<>();
for (String keys : keySet) {
JSONObject singleUser = (JSONObject) jsonObject.get(keys);
String role = singleUser.get("role").toString();
if (role.equals("Doctor")) {
doctors.add(keys);
}
}
System.out.println("Doctor users are --" + doctors);
Output -
Doctor users are --[user2]
You have embedded JSON objects that can be easily accessed by the JSON object method: (assuming 'userList' is your root JSONObject);
JSONObject user2 = userList.getJSONObject("user2");
These objects can then have their properties accessed via:
String user2Password = user2.getString("password");
Note the property 'presence' is also an embedded JSONObject, and so will have to be accessed with the JSONObject.getJSONObject() method.
So if you want to store these values in an ArrayList, simply create:
ArrayList<JSONObject> userArrayList = new ArrayList<JSONObject>();
... and then proceed to store values (probably iteratively) with:
userArrayList.add(user2);
I have this code that i used it in local host to display a listView when I upload it ,nothing is displayed in my ListView. So this what i did. Normally i get all data saved in my database but the screen is empty.
private ListView listView;
public static final String URL="http://gabes.comlu.com/Base_Controle/getAllEmp.php";
// static String TAG_JSON_ARRAY="";
private String JSON_STRING;
static JSONObject result = null;
public static final String TAG_JSON_ARRAY = "result";
private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String nom1 = jo.getString("nom");
String tele1 = jo.getString("tele");
String grade1 = jo.getString("grade");
String image1 = jo.getString("image");
String site1 = jo.getString("site");
String email1 = jo.getString("email");
HashMap<String,String> employees = new HashMap<>();
// employees.put("Type",type);
employees.put("log",nom1);
employees.put("a",tele1);
employees.put("pre",grade1);
employees.put("d",image1);
employees.put("c",site1);
employees.put("b", email1);
list.add(employees);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.list_item1,
new String[]{"log","pre","a","b","c","d"},
new int[]{R.id.id, R.id.name,R.id.a});
listView.setAdapter(adapter);
}
Your JSON_ARRAY constant has no value:
static String TAG_JSON_ARRAY="";
You are trying to get a JSONArray with an empty tag and this is why you get an Exception.
You can parse this json data using GSON library.
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<test>>() {
}.getType();
ArrayList<test> Data = (ArrayList<test>) gson.fromJson(json, listType);
Here Test is class of your json data :
public class test {
String nom;
String add;
String tele;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
}
Thank you all :)
I solved the problem by editing this :
private String JSON_STRING;
static JSONObject result = null;
......
try {
JSONArray result = new JSONArray(json);
for(int i = 0; i<result.length(); i++){
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
JSON_STRING = s;
showEmployee(s);
}
I want to make my code wait until there is a change anywhere in my class to the variable finaloutcomes. Is there any way to do this? I am carrying this out within an Asynctask, which I posted below.
public HashMap<String,String> checkbetoutcome() {
new LoadAllGamet().execute();
// INSERT CODE HERE
return finaloutcomes;
}
ASYNCTASK
class LoadAllGamet extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
// HttpParams httpParameters = new BasicHttpParams();
// HttpConnectionParams.setConnectionTimeout(httpParameters, 250000);
//HttpConnectionParams.setSoTimeout(httpParameters, 250000);
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url_check_bet);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param", bet));
// Log.d("CURRENTITEM", currentitem);
try {
post.setEntity(new UrlEncodedFormEntity(params));
} catch (IOException ioe) {
ioe.printStackTrace();
}
try {
HttpResponse response = client.execute(post);
Log.d("Http Post Responsecxxx:", response.toString());
HttpEntity httpEntity = response.getEntity();
InputStream is = httpEntity.getContent();
JSONObject jObj = null;
String json = "";
client.getConnectionManager().closeExpiredConnections();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("<", 0)) {
if (!line.startsWith("(", 0)) {
sb.append(line + "\n");
}
}
}
is.close();
json = sb.toString();
json = json.substring(json.indexOf('{'));
// Log.d("sbsssssssssss", json);
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
allgames = jObj.getJSONArray("bets");
// Log.d("WHAT IS MY ARRAY?", allgames.toString());
for (Integer i = 0; i < allgames.length(); i++) {
HashMap<String,String> statuses = new HashMap<>();
JSONObject c = allgames.getJSONObject(i);
JSONArray currentbet = c.getJSONArray("bet");
Log.d("Single array",currentbet.toString());
// Storing each json item in variable
for (Integer a = 0; a < currentbet.length();a++) {
JSONObject d = currentbet.getJSONObject(a);
String Result = d.getString("Result");
String id = d.getString("gid");
Log.d("RESULTS",Result);
statuses.put(id, Result);
}
allbetsmap.add(i, statuses);
Log.d("ddd", statuses.toString());
Log.d("AAA", allbetsmap.get(i).toString());
}
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
}
catch (IOException e) {
e.printStackTrace();
}
return "";
}
#Override
protected void onPostExecute(String param) {
Log.d("SIZE",Integer.toString(allbetsmap.size()));
//ArrayList<Map<String,String>> allbetsmap = new ArrayList<>();
//ArrayList<Map<String,String>> passtocheck = new ArrayList<>();
if (allbetsmap.size() == passtocheck.size()) {
for (int i = 0; i < allbetsmap.size();i++) {
if (allbetsmap.get(i).size() == passtocheck.get(i).size()) {
String finaloutcome = "won";
for (String a : allbetsmap.get(i).keySet()) {
String f = allbetsmap.get(i).get(a);
if(f.equals("null")) {
finaloutcome = "open";
}
else if (! (f.equals(passtocheck.get(i).get(a)))) {
finaloutcome = "lost";
break;
}
}
finaloutcomes.put(Integer.toString(i),finaloutcome);
}
}
}
Log.d("Vital",finaloutcomes.toString());
}
}
Ok, forget what I wrote before. I didn't realize you were writing code for android. Here is an improved version of LoadAllGamet. There are two important things here. 1. define as much as possible locally i.e. inside a method or - if that's not possible - inside the class. 2. return the result instead of putting it into some variable.
class LoadAllGamet extends AsyncTask<String, Void, HashMap<String,String>> {
protected HashMap<String,String> doInBackground(String ... args) {
HashMap<String,String> finaloutcomes = new HashMap<>(),
HashMap<Integer, HashMap<String,String>> allbetsmap = new HashMap<>();
HttpClient client = new DefaultHttpClient();
...
Log.d("SIZE",Integer.toString(allbetsmap.size()));
if (allbetsmap.size() == passtocheck.size()) {
...
}
Log.d("Vital",finaloutcomes.toString());
return finaloutcomes;
}
}
Whenever you want to do something that might take some time you should not run
that in the UI thread of you App since it can block your UI.
Instead run it asynchronously. One way of doing this is to use AsyncTask.
Let's assume you want to do something and while that something is being processed
you also want to update the UI (e.g. progress bars) from time to time. And once you
are finished you want to do something else with the result.
Here is one way of writing this.
void doSomething() {
new AsyncTask<String, Progress, Result>() {
protected Result doInBackground(String... args) {
//some code
publishProgress(values);
//some more code
return result;
}
protected void onProgressUpdate(Progress ... values) {
updateProgessBars(values);
}
protected void onPostExecute(Result result) {
doSomethingElse(result);
}
}.execute();
}
The String in new AsyncTask<String, Progress, Result> is the type of the
arguments to doInBackground. Often however you don't really need that unless
you want to pass arguments into execute.
Progress is the type of the values you want to send to onProgressUpdate. That
one you only need if you want to update your UI while the background processing
is still going on.
Result is of course your result type. Whatever you want to happen after
the doInBackground is finished you write into onPostExecute.
I have a listview that is populated thru SQLite with cache data. After it finishes loading. in the background I check for new data and get a returned JSON result from a MySQL db.
In my onPostExecute of this background task, when this code is ran (the code below), and while it is being looped thru (a maximum of 50 loops), the UI thread is blocked and scrolling a ListView is not possible. Here is code:
if (result.length() != 0) {
JSONArray jArray = new JSONArray(result);
JSONObject json_data = null;
for (int ii = 0; ii < jArray.length(); ii++) {
json_data = jArray.getJSONObject(ii);
item = json_data.getString("item");
cat = json_data.getString("category");
user = json_data.getString("username");
userId = json_data.getLong("user_id");
review = json_data.getString("review");
reviewId = json_data.getLong("review_id");
itemId = json_data.getLong("item_id");
commentCount = json_data.getLong("commentCount");
url = json_data.getString("name");
url = pathUrl + url; // for profile icon
date = json_data.getString("date");
rating = json_data.getDouble("rating");
upVote = json_data.getLong("good");
wiki = json_data.getString("wiki");
watchItems.add(item);
watchCats.add(cat);
watchUsers.add(user);
watchReviews.add(review);
watchUrl.add(url);
watchDateList.add(date);
watchWikiList.add(wiki);
watchItemIdList.add(String.valueOf(itemId));
watchUserIds.add(String.valueOf(userId));
watchReviewId.add(String.valueOf(reviewId));
watchRating.add(String.valueOf(rating));
watchCommentCount.add(String.valueOf(commentCount));
watchUpVote.add(String.valueOf(upVote));
Rateit.haveFollowing = "1";
if (Rateit.isUserLoggedIn == true) {
boolean oldReview = datasource
.getReviewIds(reviewId);
if (!oldReview) {
// Cache Network Items
datasource.createTrendWatch(itemId, item,
review, reviewId, cat, user,
String.valueOf(userId), url, date,
commentCount, rating, upVote, 0,
wiki);
}
}
FollowingItems wti = new FollowingItems(
Long.valueOf(watchItemIdList.get(i)),
watchItems.get(i), watchCats.get(i),
watchReviews.get(i),
Long.valueOf(watchReviewId.get(i)),
watchUsers.get(i),
Long.valueOf(watchUserIds.get(i)),
watchUrl.get(i), watchDateList.get(i),
Long.valueOf(watchCommentCount.get(i)),
Double.valueOf(watchRating.get(i)),
Long.valueOf(watchUpVote.get(i)),
watchWikiList.get(i++));
watchingListObject.add(wti);
}
}
Why is this happening? And how can I prevent my code to prevent this? Are there any optimizations I can make?
Edit: Someone below requested full task code.
Below repeats the code above but in context with entire task.
public static class FollowingTask extends AsyncTask<String, String, Void> {
protected InputStream is = null;
protected String result = "";
protected String userId;
protected ArrayList<FollowingItems> watchingListObject;
protected Context mContext;
public FollowingTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
if (mContext != null && (fromRefresh == false)) {
((MainFragmentActivity) mContext)
.setSupportProgressBarIndeterminateVisibility(true);
}
resetLists();
if (PrefActivity.getUserLoggedInStatus(mContext) == true) {
userId = PrefActivity.getLoggedInUserId(mContext);
} else {
userId = "-1";
}
super.onPreExecute();
}
#Override
protected Void doInBackground(String... params) {
datasource.purgeItemWatchingTable();
Log.d("1", "Back");
String url_select = "http://www.---.info/includes_mc_php/featured_watching.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("user_id", userId));
param.add(new BasicNameValuePair("v2", "true"));
try {
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
// read content
is = httpEntity.getContent();
} catch (Exception e) {
e.printStackTrace();
}
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void v) {
String pathUrl = Rateit.PROFILE_PIC_URL;
String item, cat, user, review, url, date, following, wiki;
long itemId, reviewId, userId, commentCount, upVote;
double rating;
int i = 0;
watchingListObject = new ArrayList<FollowingItems>();
try {
String c = String.valueOf(result.charAt(0));
if (c.equals("{")) {
JSONObject jsonObject = new JSONObject(result);
following = jsonObject.getString("following");
if (following.equals("0")) {
Rateit.haveFollowing = "0";
}
} else {
if (result.length() != 0) {
JSONArray jArray = new JSONArray(result);
JSONObject json_data = null;
for (int ii = 0; ii < jArray.length(); ii++) {
json_data = jArray.getJSONObject(ii);
item = json_data.getString("item");
cat = json_data.getString("category");
user = json_data.getString("username");
userId = json_data.getLong("user_id");
review = json_data.getString("review");
reviewId = json_data.getLong("review_id");
itemId = json_data.getLong("item_id");
commentCount = json_data.getLong("commentCount");
url = json_data.getString("name");
url = pathUrl + url; // for profile icon
date = json_data.getString("date");
rating = json_data.getDouble("rating");
upVote = json_data.getLong("good");
wiki = json_data.getString("wiki");
watchItems.add(item);
watchCats.add(cat);
watchUsers.add(user);
watchReviews.add(review);
watchUrl.add(url);
watchDateList.add(date);
watchWikiList.add(wiki);
watchItemIdList.add(String.valueOf(itemId));
watchUserIds.add(String.valueOf(userId));
watchReviewId.add(String.valueOf(reviewId));
watchRating.add(String.valueOf(rating));
watchCommentCount.add(String.valueOf(commentCount));
watchUpVote.add(String.valueOf(upVote));
Rateit.haveFollowing = "1";
if (Rateit.isUserLoggedIn == true) {
boolean oldReview = datasource
.getReviewIds(reviewId);
if (!oldReview) {
// Cache Network Items
datasource.createTrendWatch(itemId, item,
review, reviewId, cat, user,
String.valueOf(userId), url, date,
commentCount, rating, upVote, 0,
wiki);
}
}
FollowingItems wti = new FollowingItems(
Long.valueOf(watchItemIdList.get(i)),
watchItems.get(i), watchCats.get(i),
watchReviews.get(i),
Long.valueOf(watchReviewId.get(i)),
watchUsers.get(i),
Long.valueOf(watchUserIds.get(i)),
watchUrl.get(i), watchDateList.get(i),
Long.valueOf(watchCommentCount.get(i)),
Double.valueOf(watchRating.get(i)),
Long.valueOf(watchUpVote.get(i)),
watchWikiList.get(i++));
watchingListObject.add(wti);
Log.d("1", "Post 2");
}
} else {
Rateit.haveFollowing = "2";
}
}
} catch (JSONException e1) {
e1.printStackTrace();
Rateit.haveFollowing = "2";
} catch (ParseException e1) {
e1.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.d("1", "Post COMPLETE");
mPullRefreshListView.onRefreshComplete();
// Reset Trending List on Pull-to-Refresh
if (mContext != null) {
if (watchUsers.size() == 0) {
l.setVisibility(View.VISIBLE);
tv.setTypeface(TypeFace.get(mContext, Rateit.BPREPLAY));
} else {
l.setVisibility(View.GONE);
}
if (mContext != null) {
listView.setAdapter(null);
if (watchItems.size() > 0) {
wAdapter = new FollowingAdapter(mContext,
watchingListObject, TypeFace.get(mContext,
Rateit.BPREPLAY), TypeFace.get(
mContext, Rateit.ROBOTO_LIGHT),
TypeFace.get(mContext, Rateit.ROBOTO_THIN),
TypeFace.get(mContext, Rateit.ROBOTO_REGULAR));
listView.setAdapter(wAdapter);
}
}
}
if (mContext != null && (fromRefresh == false)) {
((MainFragmentActivity) mContext)
.setSupportProgressBarIndeterminateVisibility(false);
MainFragmentActivity.dismissDialog(mContext);
}
fromRefresh = false;
}
}
onPostExecute runs on the UI thread. It will block the UI. doInBackground runs in the background. You should perform heavy opertaions in the doInBackground (not in onPostExecute)
Solution: you should move the parsing etc. from the onPostExecute to doInBackground and use the onPostExecute just for binding the processed information to the UI.
I would suggest as first thing to profile that code and measure how much time exactly is spent to execute it. This way at least you understand if your problem is really here or somewhere else
I was just wondering if my code is ok in terms of downloading. My app needs a lot of data from a database so quick download times are crucial. The download time is ok but I think it can be programmed more efficient. Can you have a look at this? This class downloads many different companies and when downloaded they are put in a HashMap corresponding to their category. When finished downloading this class return a HashMap which contains multiple Hashmaps(categories) and in these Hashmaps the downloaded data. Dont mind the actual workflow but please concentrate on the way this class downloads data. Is there a way to do this faster?
public class CompanyDAO {
private static Controller delegate;
private static String companyUrl = "http:// URL HERE";
private Map<Object, Object> companyMap = new HashMap<Object, Object>();
private Map<String, Integer> pinMap = new HashMap<String, Integer>();
public CompanyDAO (Controller _delegate, Map<String, Integer> map) {
delegate = _delegate; //reference to controller
pinMap = map;
}
public void getCompanyData(ArrayList<Object> categoriesArray) {
for (int i = 0; i < categoriesArray.size(); i++) {
Map<String, Object> categoriesInMap = new HashMap<String, Object>();
//ArrayList<Object> categoriesInMapArray = new ArrayList<Object>();
companyMap.put(categoriesArray.get(i), categoriesInMap);
}
this.downloadCompanyData();
}
private void downloadCompanyData() {
companyUrl = companyUrl + delegate.ID;
try {
new DownloadCompanyData().execute(companyUrl).get(10000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class DownloadCompanyData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#SuppressWarnings("unchecked")
#Override
protected void onPostExecute(String result) {
JSONArray companyDataArray;
try {
companyDataArray = new JSONArray(result);
for(int i=0;i<companyDataArray.length();i++){
JSONObject id = companyDataArray.getJSONObject(i);
String catName = id.getString(Controller.CAT_NAME);
if (companyMap.get(catName) != null) {
Markers marker = new Markers(new LatLng(id.getDouble("latitude"), id.getDouble("longitude")), id.getString(Controller.CAT_NAME), id.getString(Controller.ID), id.getString(Controller.SUBSCRIPTION), pinMap.get(catName), id.getString(Controller.TITLE), id.getString(Controller.COMPANY_NAME), id.getString(Controller.WWW), id.getString(Controller.STREET), id.getString(Controller.HOUSE_NUMBER), id.getString(Controller.HOUSE_ADD));
((Map<String,Object>) companyMap.get(catName)).put(id.getString(Controller.TITLE), marker.markerInformationMap);
}
}
delegate.setCompanyHashMap(companyMap);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I guess you're missing the point of the AsyncTask
it's supposed to do all the work in doInBackground() and then use the onPostExecute to deliver it to the UI.
But what you're doing is doing the network operation on doInBackground and doing data parsing on onPostExecute.
Furthermore, a JSON object is a raw data that needs further parsing. You should do all the parsing on the background. For example, let's say your companyData is address, phone number, size and name. You could have a class like this (p.s. I'm writing all this without testing, there will be a little mistake here in there, but you'll get the idea):
public class CompanyData{
private String name, address, phone;
private int size;
public CompanyData(JsonObject jo){
name = jo.getString("name");
address = jo.getString("address");
phone = jo.getString("phone");
size = jo.getInt("size");
}
// put a bunch of get methods here...
// getName(), getAddress(), etc.
}
then on your 'protected Map doInBackground(String... urls) ' you complete the network operation, create the JsonArray, create a Map<String,CompanyData>, loop through the array creating CompanyData objects and placing them into the Map and return the map to your protected void onPostExecute(Map<String,CompanyData> result) and inside the post execute it's just pass this result to the UI.
happy coding.
I always doing something like this..
...
private ProgressDialog pDialog;
ArrayList<HashMap<String, String>> CompanyList;
JSONParser jParser = new JSONParser();
JSONArray Company = null;
static String url_all_company = "http://your_site/files.php";
....
private class CompanyData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Load data..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
CompanyList = new ArrayList<HashMap<String, String>>();
// Building Parameters if any.. to fetching all data, don't declare any param
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("uid", uid));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_company, "POST", param);
// Check your log cat for JSON reponse
Log.d("All Company: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// Company found
// Getting Array of Company
Company = json.getJSONArray(TAG_COMPANIES);
// looping through All Company
for (int i = 0; i < Company.length(); i++) {
JSONObject json = Company.getJSONObject(i);
// Storing each json item in variable
String id = json.getString(TAG_GID);
String name = json.getString(TAG_NAME);
String jml = json.getString(TAG_EMPLOYEE);
String deskripsi = json.getString(TAG_DESKRIPSI);
String logo = json.getString(TAG_LOGO);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_GID, id);
map.put(TAG_NAME, name);
map.put(TAG_EMPLOYEE, jml);
map.put(TAG_DESKRIPSI, deskripsi);
map.put(TAG_LOGO, logo);
// adding HashList to ArrayList
CompanyList.add(map);
}
} else {
// no CompanyList found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing data ArrayList
adapter=new LazyAdapter(MainActivity.this, CompanyList);
list.setAdapter(adapter);
pDialog.dismiss();
}
}