Hashmap size is not constant - android

I want to retrieve values from a Hash map. When i tried to display the size of a Hashmap in a TextView the size changes in my screen. Any ideas why?
Is there any other way instead of using Hashmap to store the JSONArray so it is more easy to retrieve values?
public void updateJSONdata() {
cafebartablesList = new ArrayList<HashMap<String, Integer>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(READ_COMMENTS_URL);
try {
cafebartables = json.getJSONArray(TAG_POSTS);
for (int i = 0; i < cafebartables.length(); i++) {
LoadMap ld = new LoadMap();
ld.execute();
JSONObject c =cafebartables.getJSONObject(i);
int tableId = c.getInt(TAG_TABLE_ID);
int tableMarginLeft = c.getInt(TAG_MARGIN_LEFT);
int tableMarginTop = c.getInt(TAG_MARGIN_TOP);
int isFree = c.getInt(TAG_ISFREE);
map = new HashMap<String, Integer>();
map.put(TAG_TABLE_ID, tableId);
map.put(TAG_MARGIN_LEFT, tableMarginLeft);
map.put(TAG_MARGIN_TOP, tableMarginTop);
map.put(TAG_ISFREE, isFree);
cafebartablesList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void printMap() {
mapcounter ++;
length_txt =(TextView)findViewById(R.id.length_txt);
length_txt.setText("the size is " +cafebartablesList.size());
}
public class LoadMap extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... arg0) {
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
printMap();
}
}

You're method is executing an asynctask that's recursively calling itself, which is probably causing some weird behavior.
Try something like this instead. have your print method call your asynctask. Your asynctask calls updateJSONdata, which iterates over the json object and constructs your map. At the end of your asynctask, update your textview with the size of your map.
public void updateJSONdata() {
cafebartablesList = new ArrayList<HashMap<String, Integer>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(READ_COMMENTS_URL);
try {
cafebartables = json.getJSONArray(TAG_POSTS);
for (int i = 0; i < cafebartables.length(); i++) {
JSONObject c =cafebartables.getJSONObject(i);
int tableId = c.getInt(TAG_TABLE_ID);
int tableMarginLeft = c.getInt(TAG_MARGIN_LEFT);
int tableMarginTop = c.getInt(TAG_MARGIN_TOP);
int isFree = c.getInt(TAG_ISFREE);
map = new HashMap<String, Integer>();
map.put(TAG_TABLE_ID, tableId);
map.put(TAG_MARGIN_LEFT, tableMarginLeft);
map.put(TAG_MARGIN_TOP, tableMarginTop);
map.put(TAG_ISFREE, isFree);
cafebartablesList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void printMap() {
LoadMap ld = new LoadMap();
ld.execute();
}
public class LoadMap extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... arg0) {
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
length_txt =(TextView)findViewById(R.id.length_txt);
length_txt.setText("the size is " +cafebartablesList.size());
}
}
}
Otherwise, you could use something like Gson, create a POJO for your cafebartablesList and call
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyPojo.class, new MyDeserializer())
.build();
MyPojo mp = gson.fromJson(json, MyPojo.class);

Related

How to set List Adapter in onPostExecute Asynctask?

Good Day everyone,
I have some problem here. I make a web service call in AsyncTask DoInBackground.
And I wanted to set list adapter, but I got error
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
Now how to set list adapter in post execute or something?
My code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
progressBar = (ProgressBar)findViewById(R.id.prgLoading);
//Initialize the ListView
final ListView lvProf = (ListView)findViewById(R.id.lvProfile);
//call the asynctask cals and add item to the list.
new LoadDataForActivity().execute();
//Set adapter , but i got error here
lvProf.setAdapter(new ListProfileAdapter(this,mItems));
}
private class LoadDataForActivity extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressBar.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(false);
progressBar.setClickable(false);
}
#Override
protected Void doInBackground(Void... params) {
getAll();
getTotalLeaveBalance();
getMedicalBalance();
return null;
}
#Override
protected void onPostExecute(Void result) {
//here is I add the item to my list (mitems)
try{
ResponseServiceMedicalBalance = ResponseServiceMedicalBalance.replace("\\\"", "\"");
ResponseServiceMedicalBalance = ResponseServiceMedicalBalance.substring(1, ResponseServiceMedicalBalance.length() - 1);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(ResponseServiceMedicalBalance);
String Status = jsonObject.get("Status").toString();
if (Status == "true") {
// JSONArray structure = (JSONArray) jsonObject.get("DataList");
String dataku = jsonObject.get("DataList").toString();
mItems = new ArrayList<ListProfileItem>();
try {
dataku = ANGGACRYYPT.decrypt(Enc_Pass, dataku);
}catch (GeneralSecurityException e){
//handle error - could be due to incorrect password or tampered encryptedMsg
}
JSONParser parser = new JSONParser();
JSONArray structure = (JSONArray) parser.parse(dataku);
for (int i = 0; i < structure.size(); i++) {
JSONObject data = (JSONObject) structure.get(i);
item = new ListProfileItem();
item.claimpostname = data.get("claim_post_name").toString();
String claimamount = data.get("max_limit_per_year").toString();
if (claimamount!=("0.0"))
{
Double amount = Double.parseDouble(claimamount);
DecimalFormat formatter = new DecimalFormat("#,###.00");
String AmountFormatted = formatter.format(amount);
item.claimpostamount = AmountFormatted;
}
else
{
item.claimpostamount = data.get("max_limit_per_year").toString();
}
mItems.add(item);
}
// initialize and set the list adapter
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
There are several ways of solving this, One of the quick and dirtiest is:
Change your AsyncTaskActivity Like this:
private class LoadDataForActivity extends AsyncTask<Void, Void, Void> {
private ListView listView;
private Context context;
public LoadDataForActivity(ListView listView,Context context){
this. listView = listView;
this.context = context;
}
#Override
protected void onPreExecute() {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressBar.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(false);
progressBar.setClickable(false);
}
#Override
protected Void doInBackground(Void... params) {
getAll();
getTotalLeaveBalance();
getMedicalBalance();
return null;
}
#Override
protected void onPostExecute(Void result) {
//here is I add the item to my list (mitems)
try{
ResponseServiceMedicalBalance = ResponseServiceMedicalBalance.replace("\\\"", "\"");
ResponseServiceMedicalBalance = ResponseServiceMedicalBalance.substring(1, ResponseServiceMedicalBalance.length() - 1);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(ResponseServiceMedicalBalance);
String Status = jsonObject.get("Status").toString();
if (Status == "true") {
// JSONArray structure = (JSONArray) jsonObject.get("DataList");
String dataku = jsonObject.get("DataList").toString();
mItems = new ArrayList<ListProfileItem>();
try {
dataku = ANGGACRYYPT.decrypt(Enc_Pass, dataku);
}catch (GeneralSecurityException e){
//handle error - could be due to incorrect password or tampered encryptedMsg
}
JSONParser parser = new JSONParser();
JSONArray structure = (JSONArray) parser.parse(dataku);
for (int i = 0; i < structure.size(); i++) {
JSONObject data = (JSONObject) structure.get(i);
item = new ListProfileItem();
item.claimpostname = data.get("claim_post_name").toString();
String claimamount = data.get("max_limit_per_year").toString();
if (claimamount!=("0.0"))
{
Double amount = Double.parseDouble(claimamount);
DecimalFormat formatter = new DecimalFormat("#,###.00");
String AmountFormatted = formatter.format(amount);
item.claimpostamount = AmountFormatted;
}
else
{
item.claimpostamount = data.get("max_limit_per_year").toString();
}
mItems.add(item);
}
listView.setAdapter(new ListProfileAdapter(context,mItems));
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
And you can call the asyncTask like this:
new LoadDataForActivity(listView,this).execute();
Initialise mItems as
mItems = new ArrayList<>();
Create object for ListProfileAdapter
ListProfileAdapter adapter = new ListProfileAdapter(this,mItems);
lvProf.setAdapter(adapter);
Add items in mItems
mItems.add(item);
After all items added to the list notify the adapter
adapter.notifyDataSetChanged();
move it from onCreate to onPostExecute()
define instance of Adapter as global variable then add Items in doInBackground() & call setAdapter onPostExec.
//Set adapter , but i got error here >> move it to onPostExecute
lvProf.setAdapter(new ListProfileAdapter(this,mItems));
I think the following line should be before setting your adapter,
mItems = new ArrayList<ListProfileItem>();
adapter = new ListProfileAdapter(this,mItems)
lvProf.setAdapter(adapter);
Make the instance variable,
ListProfileAdapter adapter;
instead of putting in the Asynctask. After finishing the asynctask in onPostExecute you also need to run,
adapter.notifyDatasetChanged();

How to Reload a Page while clicked on Button?

In my Application I want to retrieve a data from the database. But the problem I am facing is that, the data is fetched from database but it is not displaying at a time when I reopen the page at that time the data is displaying. I want to reload a page when I click on Button.
Here the code is as follow :-
Btngetdata.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new InTimeInsert().execute();
}
});
private class InTimeInsert extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... args) {
try {
arraylist = new ArrayList<HashMap<String, String>>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("at_username", uid));
JSONObject json = jParser.makeHttpRequest(url_intime,"GET", params);
//ownerObj = json.getJSONArray("visit");
for (int i = 0; i < ownerObj.length(); i++) {
jsonobject = ownerObj.getJSONObject(i);
time_fetch.add(jsonobject.getString("at_itime"));
}
} catch (Exception e) {
}
return null;
}
#Override
protected void onPostExecute(Void args) {
ina.setText(""+delivery_fetch);
}
}
private class AllAtendence extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... args) {
try {
arraylist = new ArrayList<HashMap<String, String>>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("at_username", uid));
JSONObject json = jParser.makeHttpRequest(url_allatendence,"GET", params);
ownerObj = json.getJSONArray("visit");
for (int i = 0; i < ownerObj.length(); i++) {
jsonobject = ownerObj.getJSONObject(i);
delivery_fetch =jsonobject.getString("at_date");
lunch=jsonobject.getString("at_litime");
rejoin=jsonobject.getString("at_lotime");
out=jsonobject.getString("at_otime");
Log.d("at_line",json.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
ina.setText(""+delivery_fetch);
rejoina.setText(""+lunch);
luncha.setText(""+rejoin);
outa.setText(""+out);
if(ina.getText().toString().equals(""))
{
Btngetdata.setVisibility(View.VISIBLE);
inti.setVisibility(View.GONE);
}
else
{
Btngetdata.setVisibility(View.GONE);
}
if(luncha.getText().toString().equals(""))
{
ltime.setVisibility(View.VISIBLE);
luncht.setVisibility(View.GONE);
}
else
{
ltime.setVisibility(View.GONE);
}
if(rejoina.getText().toString().equals(""))
{
rtime.setVisibility(View.VISIBLE);
rejoint.setVisibility(View.GONE);
}
else
{
rtime.setVisibility(View.GONE);
}
if(outa.getText().toString().equals(""))
{
otime.setVisibility(View.VISIBLE);
outt.setVisibility(View.GONE);
}
else
{
otime.setVisibility(View.GONE);
}
}
}
If you fetch only one data than you can use this to solve your problem..
And use log to see if there is any err on fetching data... on catch block..Good luck.
private class InTimeInsert extends AsyncTask<Void, Void, Void> {
String fetched_data = "";
#Override
protected Void doInBackground(Void... args) {
try {
arraylist = new ArrayList<HashMap<String, String>>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("at_username", uid));
JSONObject json = jParser.makeHttpRequest(url_intime,"GET", params);
//ownerObj = json.getJSONArray("visit");
for (int i = 0; i < ownerObj.length(); i++) {
jsonobject = ownerObj.getJSONObject(i);
this.fetched_data = jsonobject.getString("at_itime");
}
} catch (Exception e) {
Log.d("fetch err", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void args) {
ina.setText(""+this.fetched_data);
}
}
//put your code in onResume methods
#Override protected void onResume() {
super.onResume();
// call here
new InTimeInsert().execute();
}
Add .get();, while calling AsyncTask.
Like:
new InTimeInsert().execute().get();
It waits for the result of AsyncTask.
By doing this, will execute the AsyncTask first and then continues with the control flow.

Iterate through a Hashmap and store values in variables for use

Hello I retrieved some data from a MySQL database and I stored this data in a Hashmap. I also have created a class which has the same variables as the Hashmap. I want to iterate through the Hashmap and store the values so I can use them for each object. Any ideas how to do it?
public void updateJSONdata() {
cafebartablesList = new ArrayList<HashMap<String, Integer>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(READ_COMMENTS_URL);
try {
cafebartables = json.getJSONArray(TAG_POSTS);
for (int i = 0; i < cafebartables.length(); i++) {
JSONObject c =cafebartables.getJSONObject(i);
int tableId = c.getInt(TAG_TABLE_ID);
int tableMarginLeft = c.getInt(TAG_MARGIN_LEFT);
int tableMarginTop = c.getInt(TAG_MARGIN_TOP);
int isFree = c.getInt(TAG_ISFREE);
map = new HashMap<String, Integer>();
map.put(TAG_TABLE_ID, tableId);
map.put(TAG_MARGIN_LEFT, tableMarginLeft);
map.put(TAG_MARGIN_TOP, tableMarginTop);
map.put(TAG_ISFREE, isFree);
cafebartablesList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void printMap() {
LoadMap ld = new LoadMap();
ld.execute();
}
public class LoadMap extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... arg0) {
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
}
}
}
Why do you want to do that? You're making your life difficult. There's a LinkedHashMap behind every JSONObject, so just use the JSONObject as is, without any conversion. I.e., use ArrayList<JSONObject> instead.

preference activity from dynamic array

getting data from webservices but values not getting out of async class,
public class Settings extends PreferenceActivity{
ListPreference lst1;
public static String[] batcharr;
public static String[] streamarr;
public Settings(){
// TPGetListone getlist = new TPGetListone();
// getlist.execute();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings);
lst1 = (ListPreference) findPreference("prefStream");
TPGetListone getlist = new TPGetListone();
getlist.execute();
lst1.setEntries(batcharr);
lst1.setEntryValues(batcharr);
}
public class TPGetListone extends AsyncTask<String, Void, Void> {
String datax = "";
JSONArray array;
List<String> lstbatch;
List<String> lststream;
private String LogStr = "Panchratna";
#Override
protected Void doInBackground(String... params) {
DataHelper gd = new DataHelper("http://xxxx.com/EventGetter","http://xxxx.com/EventGetter.asmx?wsdl","http://xxxx.com/EventGetter/GetCourseList","GetCourseList");
datax = gd.GetData("query","SELECT batch, stream FROM batch");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Log.i(LogStr, "onPostExecuteCATALOG");
try {
array = new JSONArray(datax);
} catch (JSONException e) {
e.printStackTrace();
}
lstbatch = new ArrayList<String>();
lststream = new ArrayList<String>();
for(int i = 0; i < array.length(); i++){
try {
lstbatch.add(array.getJSONObject(i).getString("batch"));
lststream.add(array.getJSONObject(i).getString("stream"));
} catch (JSONException e) {
e.printStackTrace();
}
}
batcharr = new String[lstbatch.size()];
streamarr = new String[lststream.size()];
for (int i=0;i<lststream.size();i++){
lststream.toArray(batcharr);
lstbatch.toArray(streamarr);
}
}
#Override
protected void onCancelled(Void aVoid) {
super.onCancelled(aVoid);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
}
i know this is not a proper way,
i m using webservices to fetch json values and convert it to list<>
by debugging, values do come in List which is lstbatch and lststream,
and array batcharr and streamarr ,
but when the task executes , in on create method , batcharr and streamarr is showing error,
same method worked last time on an Activity
Please help ,
Thank You
Move this code above the Async and it will be accessible
List<String> lstbatch;
List<String> lststream;
public class TPGetListone extends AsyncTask<String, Void, Void> {
String datax = "";
JSONArray array;
//--> Remove to Up -->List<String> lstbatch;
//--> Remove to Up -->List<String> lststream;
private String LogStr = "Panchratna";
EDIT
for (int i=0;i<lststream.size();i++){
batcharr[i]=lststream.get(i);
streamarr[i]=lstbatch.get(i);
}
put this code
lst1.setEntries(batcharr);
lst1.setEntryValues(batcharr);
in
PostExecute method
protected void onPostExecute(Void aVoid) {
Log.i(LogStr, "onPostExecuteCATALOG");
try {
array = new JSONArray(datax);
} catch (JSONException e) {
e.printStackTrace();
}
lstbatch = new ArrayList<String>();
lststream = new ArrayList<String>();
for(int i = 0; i < array.length(); i++){
try {
lstbatch.add(array.getJSONObject(i).getString("batch"));
lststream.add(array.getJSONObject(i).getString("stream"));
} catch (JSONException e) {
e.printStackTrace();
}
}
batcharr = new String[lstbatch.size()];
streamarr = new String[lststream.size()];
for (int i=0;i<lststream.size();i++){
lststream.toArray(batcharr);
lstbatch.toArray(streamarr);
}
===> lst1.setEntries(batcharr);
===> lst1.setEntryValues(batcharr);
}

Asynctask wont update array

I am having a problem accessing the arraylists populated by this asynctask from class file A. From Class file B I try to use A a method such as
inStream = new InboxLoader(MainInbox.this,1);
Log.e("JJJ",""+inStream.getMemId().size());
method from a different class file I get a crash in logcat saying indexoutofbounds error
I was looking for an alternative to having this AsyncTask in the same file as class B
public class InboxLoader {
Context ctx;
ArrayListmemName,memAvatar,msgBody,msgTime;
ArrayList msgId,memId;
InboxLoader(Context context,int id){
this.ctx = context;
this.msgBody = new ArrayList<String>();
this.memAvatar = new ArrayList<String>();
this.memId = new ArrayList<Integer>();
this.memName = new ArrayList<String>();
this.msgTime = new ArrayList<String>();
this.msgId = new ArrayList<Integer>();
new LoadStream().execute(id);
}
public ArrayList<String> getMsgBody(){
return msgBody;
}
public ArrayList<String> getMemAvatar(){
return memAvatar;
}
public ArrayList<Integer> getMemId(){
return memId;
}
public ArrayList<String> getMemName(){
return memName;
}
public ArrayList<Integer> getMsgId(){
return msgId;
}
public ArrayList<String> getMsgTime(){
return msgTime;
}
/*
* STARTS GRABBING DATA FOR THE LISTVIEW
*/
public class LoadStream extends AsyncTask<Integer, Integer, JSONObject> {
ProgressDialog progressBar;
#Override
protected void onPreExecute() {
progressBar = new ProgressDialog(ctx, ProgressDialog.STYLE_SPINNER);
progressBar.setMessage("Generating Inbox....");
progressBar.show();
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(Integer... params) {
List<NameValuePair> params2 = new ArrayList<NameValuePair>();
params2.add(new BasicNameValuePair("memberId", String.valueOf(1)));
params2.add(new BasicNameValuePair("type", "get"));
JSONObject json = new jsonParser().makeRequest("url", params2);
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
super.onPostExecute(json);
int success = 0;
JSONObject jData;
JSONArray jObj = null;
try{
// successfully received details
jObj = json.getJSONArray("details"); // JSON Array
success = json.getInt("success");
}catch(Exception e){
e.printStackTrace();
}
if(success == 1){
try{
for( int i = 0; i < jObj.length(); i++ ){
//GET OBJECT FROM JSON Array
jData = jObj.getJSONObject(i);
//ASSIGN VALUES
msgId.add(jData.getInt("msg_id"));
memAvatar.add(jData.getString("mem_avatar"));
memName.add(jData.getString("mem_name"));
memId.add(jData.getInt("mem_id"));
msgBody.add(jData.getString("msg_body"));
msgTime.add(jData.getString("msg_time"));
}
}catch(Exception e){
Log.e("STREAM FILE PROBLEM", e.getMessage());
}
}
progressBar.dismiss();
Log.e("STREAM FILE PROBLEM",""+memId.size());//prints 1
}
}
}
You are trying to read the ArrayList immediately after you start the AsyncTask, while the result will not be available until the doInBackground ends.
You should do what you want in onPostExecute to make sure the task executed all right.
Edited:
Define a listener like below:
public interface RequestListener {
public void onComplete(T response);
}
and the add a field requestListener in InboxLoader:
InboxLoader(Context context,int id, RequestListener li){
this.ctx = context;
this.msgBody = new ArrayList<String>();
this.memAvatar = new ArrayList<String>();
this.memId = new ArrayList<Integer>();
this.memName = new ArrayList<String>();
this.msgTime = new ArrayList<String>();
this.msgId = new ArrayList<Integer>();
this.requestListener = li;
new LoadStream().execute(id);
}
in the onPostExecute add this:
protected void onPostExecute(JSONObject json) {
super.onPostExecute(json);
int success = 0;
JSONObject jData;
JSONArray jObj = null;
try{
// successfully received details
jObj = json.getJSONArray("details"); // JSON Array
success = json.getInt("success");
if(requestListener!=null)
requestListener.onComplete();
}catch(Exception e){
e.printStackTrace();
}
Then you could process the result in onComplete define in your class B:
inStream = new InboxLoader(MainInbox.this,1, new RequestListener() {
public void onComplete(){
Log.e("JJJ",""+inStream.getMemId().size());
};
});

Categories

Resources