Updated: I filled an array through HashMap, Iam using Asynctask for http request & after filling array put that array in dialog box. When I first run my app it gives me an empty dialog box & didn't give any error but when I re run my app it shows all array elements in dialog box perfectly. Whats the reason ?
//JsonResponse Inner Class in main class
private class JsonResponse extends AsyncTask<String, Void, String> {
String response = "";
private ArrayList<HashMap<String, String>> prServices_resultList = new ArrayList<HashMap<String, String>>();
protected void onPreExecute()
{
}
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
int z=0;
for (HashMap<String, String> hashList : prServices_resultList)
{
Av_List[z] = hashList.get(android_Av_ID);
Av_Lat[z] = Double.parseDouble(hashList.get(android_Av_LAT));
Av_Lng[z] = Double.parseDouble(hashList.get(android_Av_LONG));
z++;
}
}
}
protected String doInBackground(final String... args)
{
JSONParser jParser = new JSONParser();
JSONArray jArrayServices = jParser.getJSONFromUrl(url_Services);
try{
for (int i = 0; i < jArrayServices.length(); i++)
{
JSONObject jsonElements = jArrayServices.getJSONObject(i);
String S_id = jsonElements.getString(android_S_ID);
String S_name = jsonElements.getString(android_S_NAME);
HashMap<String, String> hashServices = new HashMap<String, String>();
// adding each child node to HashMap key
hashServices.put(android_S_ID, S_id);
hashServices.put(android_S_NAME, S_name);
// adding HashList to ArrayList
prServices_resultList.add(hashServices);
}
response = "Success";
}
catch(JSONException e)
{
e.printStackTrace();
}
return response;
}
}
In my main class when i press a button:
new JsonResponse().execute;
In main class above onCreate i declare like:
static ArrayList<HashMap<String, String>> ResultList_Services = new ArrayList<HashMap<String, String>>();
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
Now I get an error: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
First of all, adding values to static field ResultList_Services accessible for UI-thread from the background thread is very bad practice. You should rewrite your code to be thread-safe. The are several options, here is the one:
private class JsonResponse extends AsyncTask<String, Void, String> {
private ArrayList<HashMap<String, String>> resultList = new ArrayList<HashMap<String, String>>();
...
protected String doInBackground(final String... args)
{
...
// adding HashList to private JsonResponse's field
resultList.add(hashServices);
...
}
protected void onPostExecute(String result)
{
if (response.equalsIgnoreCase("Success"))
{
ResultList_Services = resultList;
//TODO: notify your Activity/Dialog on completion
}
}
}
Concerning your question - the reason for not seeing new records, is that you show the dialog when there are no values in the ResultList. You should request to show it from onPostExecute, for example.
You need to do this -
for (HashMap<String, String> hashServices : ResultList_Services)
{
Db_Services[s] = hashServices.get(android_S_CName);
Db_ServicesID[s] = hashServices.get(android_S_ID);
s++;
}
in onPostExcecute() block of your asynctask.
Related
I have a hashmap of string
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
and a List of Hashmap
List<HashMap<String, String>> recents = new ArrayList<>();
recents.add(hashMap);
Now I have to save this list
I have tried using https://github.com/pilgr/Paper to save this List
Paper.book().write("recents", recents);
but i can't get the list back
List<HashMap<String, String>> list = Paper.book().read("recents");
HashMap<String,String> hashMap = list.get(0);
String name = hashMap.get("name");
String number = hashMap.get("number");
String image = hashMap.get("profileImage");
Uses of the code
actually I'm passing this list to recycelerViewAdapeter and from there in OnBindViewHolder() I'm getting all the Hashmap values and displaying it to user
Saving Data Code
Paper.init(this);
List<HashMap<String, String>> recents = new ArrayList<>();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
recents.add(hashMap);
Paper.book().write("recents", contacts);
Receiving Data Code
Paper.init(requireActivity());
recyclerView = view.findViewById(R.id.recyclerView);
List<HashMap<String, String>> list = Paper.book().read("recents");
Adapter = new Adapter(requireActivity(), list);
recyclerView.setAdapter(Adapter);
You can use Gson and SharedPreferences to do the same.
implementation 'com.google.code.gson:gson:2.8.9'
Example:
private SharedPreferences sp;
private HashMap<String, Boolean> favs;
....
....
public void addFavourite(String wall_name) {
favs = getFavourites();
favs.put(wall_name, true);
setFavourties();
}
public void removeFav(String wall_name) {
favs = getFavourites();
favs.put(wall_name, false);
setFavourties();
}
private void setFavourties() {
SharedPreferences.Editor pe = sp.edit();
Gson gson = new Gson();
String j = gson.toJson(favs);
pe.putString("Favourites", j);
pe.apply();
}
public HashMap<String, Boolean> getFavourites() {
Gson gson = new Gson();
String j = sp.getString("Favourites", null);
if (j != null) {
Type stringBooleanMap = new TypeToken<HashMap<String, Boolean>>() {
}.getType();
return gson.fromJson(j, stringBooleanMap);
} else {
return new HashMap<>();
}
}
I am trying to pass string and int data (possibly other data types like time) to a HashMap to use in a doinbackground task in Android to amend a URL. The URL uses key value pairs to update a mysql database.
I've read about using an object to pass multiple variable types, but can't get it to work.
private void addChore(){
final String title2 = editTextTaskTitle.getText().toString().trim();
final String description2 = editTextDescription.getText().toString().trim();
final String person2 = itemPerson.toString().trim();
final int monday2 = cbMon;
class NewChore1 {
String title1;
String description1;
String person1;
int monday1;
NewChore1(String title1, String description1, String person1, int monday1){
this.title1 = title1;
this.description1 = description1;
this.person1 = person1;
this.monday1 = monday1;
}
}
class AddChoreM extends AsyncTask<Void,Void,String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(AddChore.this,"Adding...","Wait...",false,false);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(AddChore.this,s,Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(Void... v) {
HashMap<String, NewChore1> params1 = new HashMap<>();
params1.put(Config.KEY_CHORE_TASK_TITLE,?);
params1.put(Config.KEY_CHORE_DESCRIPTION,?);
params1.put(Config.KEY_CHORE_PERSON,?);
params1.put(Config.KEY_CHORE_MONDAY,?);
RequestHandler rh = new RequestHandler();
String res = rh.sendPostRequest(Config.URL_ADD, params1);
return res;
}
}
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
AddChoreM addChoreM = new AddChoreM();
addChoreM.execute(params);
}
In RequestHandler, I have used the following.
private String getPostDataString(HashMap<String, Object> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
Edit: I was not quick enough so there are other answers already but the changes below should work. You can pass your NewChore1 object to your task and extract the parameters in doInBackground:
class AddChoreM extends AsyncTask<NewChore1,Void,String> {
And:
#Override
protected String doInBackground(NewChore1...chore) {
HashMap<String, String> params1 = new HashMap<>();
params1.put(Config.KEY_CHORE_TASK_TITLE, chore[0].title1);
params1.put(Config.KEY_CHORE_DESCRIPTION, chore[0].description1);
params1.put(Config.KEY_CHORE_PERSON,chore[0].person1);
params1.put(Config.KEY_CHORE_MONDAY,chore[0].monday1);
RequestHandler rh = new RequestHandler();
String res = rh.sendPostRequest(Config.URL_ADD, params1);
return res;
}
Finally:
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
new addChoreM.execute(params);
Update:
Since sendPostRequest only accepts HashMap<String, String> you need to change to: HashMap<String, String> params1 = new HashMap<>();
And change your NewChore1 class to take only Strings.
If you use
Map<String, Object> params1 = new HashMap<>();
then you can store any type as value within the map.
Create a constructor for AddChoreM class and set your NewChore1 object through it. You can now easily extract the properties of NewChore1 in doInBackground.
class AddChoreM extends AsyncTask<Void,Void,String> {
ProgressDialog loading;
NewChore1 newChore1Obj;
public AddChoreM(NewChore1 newChore1Obj){
this.newChore1Obj = newChore1Obj;
}
#Override
protected String doInBackground(Void...v) {
HashMap<String, NewChore1> params1 = new HashMap<>();
String res = "";
if(newChore1Obj != null) {
params1.put(Config.KEY_CHORE_TASK_TITLE, newChore1Obj.title1);
params1.put(Config.KEY_CHORE_DESCRIPTION, newChore1Obj.description1);
params1.put(Config.KEY_CHORE_PERSON,newChore1Obj.person1);
params1.put(Config.KEY_CHORE_MONDAY,newChore1Obj.monday1);
RequestHandler rh = new RequestHandler();
res = rh.sendPostRequest(Config.URL_ADD, params1);
}
return res;
}
// Other methods of AsyncTask
//
}
Finally, create and execute AddChoreM like this.
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
AddChoreM addChoreM = new AddChoreM(params);
addChoreM.execute();
I am trying to get values from a json data with AsyncTask. I am getting only the last value and I don't understand why...
I tryed to parse with for each, while but I am doing something wrong :
Here is my code :
private class DecodeData extends AsyncTask<String, Void, String> {
protected ArrayList<HashMap<String, String>> decodedArray;
protected HashMap<String, String> decodedMap;
protected Iterator<String> it;
protected JSONArray m_Array;
protected JSONObject object;
protected String response;
protected String keys;
protected String value;
#SuppressWarnings("unchecked")
#Override
protected String doInBackground(String... params) {
response = params[0];
keys = "";
value = "";
object = null;
decodedArray = new ArrayList<HashMap<String, String>>();
try {
JSONArray arrayResp = new JSONArray(response);
for (int i = 0; i < arrayResp.length(); i++) {
decodedMap = new HashMap<String, String>();
it = arrayResp.getJSONObject(i).keys();
while (it.hasNext()) {
keys = (String)it.next();
value = Base64.DecodeStrToStr((String)arrayResp.getJSONObject(i).get(keys));
decodedMap.put("\""+keys+"\"", "\""+value+"\"");
object = new JSONObject(decodedMap.toString());
Log.i("DECODED MAP : ", object.toString());
m_Array = new JSONArray();
m_Array.put(object);
Log.i("M_ARRAY", ""+m_Array);
}
// decodedArray.add(decodedMap);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// array = new JSONArray(decodedArray);
return m_Array.toString();
}
I am using Volley to get response. After that, I create a JSONArray with this response and I get all keys/values from it. I put all of them in my Hashmap. But when i'm putting keys/values here : m_Array.put(object), it puts only the last value of my json data. Anybody has an idea of what I'm making wrong ?
Please create JSONArray before starting for loop..
m_Array = new JSONArray();
JSONArray arrayResp = new JSONArray(response);
for (int i = 0; i < arrayResp.length(); i++) { ....
Updated Question from previous: I filled an array through HashMap, Iam using Asynctask for http request & after filling array put that array in dialog box. When I first run my app it gives me an empty dialog box & didn't give any error but when I re run my app it shows all array elements in dialog box perfectly. Whats the reason ?
//JsonResponse Inner Class in main class
private class JsonResponse extends AsyncTask<String, Void, String>
{
String response = "";
private ArrayList<HashMap<String, String>> prServices_resultList =
new ArrayList<HashMap<String, String>>();
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
int s=0;
for (HashMap<String, String> hashServices : prServices_resultList)
{
Db_Services[s] = hashServices.get(android_S_CName);
Db_ServicesID[s] = hashServices.get(android_S_ID);
s++;
}
}
}
protected String doInBackground(final String... args)
{
JSONParser jParser = new JSONParser();
JSONArray jArrayServices = jParser.getJSONFromUrl(url_Services);
try
{
for (int i = 0; i < jArrayServices.length(); i++)
{
JSONObject jsonElements = jArrayServices.getJSONObject(i);
String S_id = jsonElements.getString(android_S_ID);
String S_name = jsonElements.getString(android_S_NAME);
HashMap<String, String> hashServices = new HashMap<String, String>();
// adding each child node to HashMap key
hashServices.put(android_S_ID, S_id);
hashServices.put(android_S_NAME, S_name);
// adding HashList to ArrayList
prServices_resultList.add(hashServices);
}
response = "Success";
}
catch(JSONException e)
{
e.printStackTrace();
}
return response;
}
}
In my main class have have a button & when i press i execute AsyncTask:
new JsonResponse().execute;
In main class above onCreate i declare like:
static ArrayList<HashMap<String, String>> ResultList_Services =
new ArrayList<HashMap<String, String>>();
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
You are creating an empty map here:
ResultList_Services = new ArrayList<HashMap<String, String>>();
Then trying to initialize two arrays with the size of an empty map - being zero.
// ResultList_Services.size() will be zero
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
So when you try adding to these arrays it will throw an OutOfBoundsException
You could make these Arrays into lists, then you can dynamically add elements as needed without needing to specify a size to start with. If you then need an Array (for other Methods) you can get an array from a list using List#toArray()
As per your comment
You could just create temporary arrays to which you add all the elements and then assign this to your other arrays, something like
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
String[] tmp_dbServ = new String[prServices_resultList.size()];
String[] tmp_dbServID = new String[prServices_resultList.size()];
int s=0;
for (HashMap<String, String> hashServices : prServices_resultList)
{
tmp_dbServ[s] = hashServices.get(android_S_CName);
tmp_dbServID[s] = hashServices.get(android_S_ID);
s++;
}
Db_Services = tmp_dbServ;
Db_ServicesID = tmp_dbServID;
}
}
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();
}
}