I use an Asynchronous Http Client for Android for loading my JSON data.(https://github.com/h-r/android-async-http-with-caching)
It works perfect, but i want to cache json files if user has no connection.
I know how to check if user had internet connection etc, but i use a version of Asynchronous Http Client of loopj who has caching enabled for httpresponse's
The problem is that my code give's just a error..
WhtsnxtBase.get(dateje, null, new JsonHttpResponseHandler() {//get url with date of json file
#Override
public void onSuccess(JSONObject timeline) {
// code removed isn't relevant for this question
}
#Override
public void onFailure(Throwable e) {Log.e("MyActivity", "OnFailure!", e);}
#Override
public void onFailure(Throwable e, String response) {Log.e("MyActivity", "OnFailure!", e);}
#Override
public void onFailure(Throwable e, JSONArray errorResponse) {Log.e("MyActivity", "OnFailure!", e);}
});
This is the url (to see wat kind of date it is etc..http://calvijn.tk/mobiel/2013-07-19)
The cache don't work do anybody know how to fix it, or how to use the cached library properly?
If it isnt't possible this way, does anybody know a good opensource cache manager or something to cache the JSON files the right way.
I would recommend parsing these JSON responses into a local java object:
https://code.google.com/p/google-gson/
I use GSON to serialize the JSON objects into a Java Class. This makes it easier to handle the data within your app.
If you want to persist data properly when the user is offline, you may want to look into using Android's SQLite database for persisting a large array of objects. For something simple, you can use ORMLite.
Right now I'm using ORMLite and built out a custom content provider to handle local data. This allows me to use the SimpleCursorAdapter and LoaderManagers.
Inside your JsonHttpResponseHandler you get your JSON in onSuccess() so you need to cache data from there, while you have two options : store in sqlite or use file caching, onfailure() is called when you don't get your object ex no connection or timeout.
public class JSONCache
{
public static void writeToCache( String fileName ,JSONObject jObject )
{
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(fileName)));
out.writeObject( jObject );
out.close();
}
public static JSONObject readFromCache(String fileName )
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(fileName)));
JSONObject jsonObject = (JSONObject) in.readObject();
in.close();
retrun jsonObject;
}
}
and in your response handler
WhtsnxtBase.get(dateje, null, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject timeline)
{
...
JSONCache.writeToCache( "cache_file_path" , timeline );
//updateUI(timeline);
}
#Override
public void onFailure(Throwable e)
{
Log.e("MyActivity", "OnFailure!", e);
JSONCache.readFromCache( "cache_file_path" );
}
#Override
public void onFailure(Throwable e, String response)
{
Log.e("MyActivity", "OnFailure!", e);
JSONObject timeline = JSONCache.readFromCache( "cache_file_path" );
//updateUI(timeline);
}
#Override
public void onFailure(Throwable e, JSONArray errorResponse)
{
Log.e("MyActivity", "OnFailure!", e);
JSONObject timeline = JSONCache.readFromCache( "cache_file_path" );
//updateUI(timeline);
}
});
Related
I want to send parameters such as username and password.
I got an error like String cannot be converted to jsonobject.
I dont know what this happening.Anyone pls help me my code is:
JSONObject obj=new JSONObject();
try{
obj.put("username","test");
obj.put("password","test");
} catch (JSONException e) {
}
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
urlJsonObj, obj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
} catch (JSONException e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq,json_obj_req);
}
There is nothing wrong with the way you are creating JSONObject and putting values in it. Make sure the response received is Json, because your onResponse method accepts JSONObject. You could be receiving String value as response, which could not be converted to JSONObject.
It looks like your response is actually a string and not a json object i.e. {"object":"value"} but rather "object:value". You need to sniff your response via either Stetho, Fiddler or reenact your request via Postman (or Fiddler)
======================
This doesn't answer your question, but this will help you tremendously and make your life easier.
Highly recommend using Gson and Retrofit to make HTTP requests and parse Gson objects easily.
https://github.com/google/gson
http://square.github.io/retrofit/
Today I got to know that Retrofit uses gson(or any other convertor) to serialize or deserialize the json response (response that was got using okhttp or any related library).
Now, when I was naive(in some sense still am) and I used to use Volley and at that time I never used Gson or any related library and same for okhttp.But i used to get my response and inflate it successfully on my views.
1. Now does Volley internally do what Retrofit does using Gson and Okhttp?
If not? 2. Then how did i able to get values parsed without using anything?
Below is the sample Codes that i used to write:-
JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(
Request.Method.POST, URL_THUMB, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray=response.getJSONArray("server_response");
for(int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject=(JSONObject)jsonArray.get(i);
String id=jsonObject.getString("id");
String artist_name=jsonObject.getString("artist_name");
String img_id=jsonObject.getString("img_id");
listId.add(id);
listArtistName.add(artist_name);
listImgID.add(img_id);
}
recyclerView.setAdapter(comedy_adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
and now just inflate these list values to my views.
Where did I go wrong? (I don't think I was wrong as things went well and code always run fine)
In your example you're parsing the response into JSON arrays and objects manually. Converters such as Gson let you parse the response into a variable of a custom object in a single line.
For example, if I have the following model:
public class Model {
private int id;
private String name;
}
I can parse a string response using the following code:
Model model = gson.fromJson(str, Model.class);
Otherwise, you have to do it manually, like what you're doing at the moment:
JSONObject jsonObject = response.getJSONObject("str");
int id = jsonObject.getInt("id");
String name = jsonObject.getString("name");
Model model = new Model(id, name);
In Retrofit 2 you don't even have to call fromJson - you simple receive the object you expect as an input parameter in onResponse. It's very useful when dealing with more complex models.
i am fetching 104 variables from MySQL through php in android and trying to show in list view but its taking almost 1 - 2 minutes to load values how to speed up the data fetching.
i am using json for fetching data, any other library's for fast fetching.
please explain with complete example.
Try the Android Asynchronous Http Client library
Features
Using upstream HttpClient of version 4.3.6 instead of Android provided DefaultHttpClient
Compatible with Android API 23 and higher
Make asynchronous HTTP requests, handle responses in anonymous callbacks
HTTP requests happen outside the UI thread
Requests use a threadpool to cap concurrent resource usage
GET/POST params builder (RequestParams)
Multipart file uploads with no additional third party libraries
Streamed JSON uploads with no additional libraries
Handling circular and relative redirects
Tiny size overhead to your application, only 90kb for everything
Automatic smart request retries optimized for spotty mobile connections
Automatic gzip response decoding support for super-fast requests
Binary protocol communication with BinaryHttpResponseHandler
Built-in response parsing into JSON with JsonHttpResponseHandler
Saving response directly into file with FileAsyncHttpResponseHandler
Persistent cookie store, saves cookies into your app’s SharedPreferences
Integration with Jackson JSON, Gson or other JSON (de)serializing libraries with BaseJsonHttpResponseHandler
Support for SAX parser with SaxAsyncHttpResponseHandler
Support for languages and content encodings, not just UTF-8
For more details please visit these link :
http://loopj.com/android-async-http/
Here's an example of using it :
pdialog.setMessage("Veuillez patienter!");
pdialog.show();
RequestParams params = new RequestParams();
params.put("user_login", username);
AsyncHttpClient client = new AsyncHttpClient();
client.post("http://yourUrl.com", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
loading = true;
AdapterPrincipal adapterPrincipal;
String s = "";
try {
s = new String(responseBody, "UTF-8");
Log.d("Error", s.toString());
JSONObject arrg = new JSONObject(s);
JSONArray query = arrg.getJSONArray("query");
Log.i("result from query ", "" + query);
for (int i = 0; i < query.length(); i++) {
try {
pdialog.dismiss();
JSONObject object = query.getJSONObject(i);
String dateinsertannonce = object.getString("date_insert_annonce");
Log.i("date", dateinsertannonce);
String datevente = object.getString("vendu");
String marque = object.getString("marque");
String Clomn_Model = object.getString("model");
String Clomn_Prix = object.getString("prix");
String Clomn_Kilometrage = object.getString("kilometrage");
String Clomn_BoiteVitesse = object.getString("boite_vitesse");
String Clomn_Energie = object.getString("energie");
String Clomn_Source = object.getString("source");
String Clomn_Url = object.getString("url");
String Clomn_PHOTO = object.getString("images_noms");
String Maj = object.getString("derniere_maj");
int id = object.getInt("id");
voitureList = databaseHelper.getAllVoiture(username, currentLength);
listView.setAdapter(new AdapterLogin(getActivity(), voitureList, username, currentLength));
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
}
});
}
});
}
I'm trying to get response with user json list from github api.
Could anyone tell me the reason why code execution path doesn't reach overriden methods onFailure() and onSuccess?
public String getResponse()
{
AsyncHttpClient client=new AsyncHttpClient();
RequestParams params=new RequestParams();
params.put("since","0");
client.get("https://api.github.com/users", params, new AsyncHttpResponseHandler() {
#Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
userList.clear();
userList.addFirst("Items didn't load properly");
}
#Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
try {
content = new String(arg2, "UTF-8");
//content is json response that can be parsed.
} catch (UnsupportedEncodingException e1) {
userList.clear();
userList.add("Some encoding problems occured");
e1.printStackTrace();
}
}
});
return content;
}
These methods just ignored for some reason. After client.get(...) it jumps right to return content.
Any ideas about the reason of it? What am I doing wrong?
Would appreciate any advice.
EDIT:
SO the proper way is to do that is to operate with response within the onSuccess(...) method?
#Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
try {
content = new String(arg2, "UTF-8");
//content is json response that can be parsed.
parseResponseAmount(content, 10); //operate with response
} catch (UnsupportedEncodingException e1) {
userList.clear();
userList.add("Some encoding problems occured");
e1.printStackTrace();
}
}
And I try to parse information from response like:
private void parseResponseAmount (String response, int amount)
{
try {
JSONArray readerArray = new JSONArray(response);
for (int i = 0; i < amount; i++)
{
JSONObject userObject = (JSONObject) readerArray.get(i);
String login = userObject.getString("login");
getUserList().add(login);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
getUserList().clear();
getUserList().add("Failed to parse response");
e.printStackTrace();
}
}
but that code still doesn't work. In event-driven development it caused by mouse move, key presses etc. What causes these onSuccess() and onFailure() to occur? What is the precondition?
You're using AsyncHttpClient. Do you know what "Async" means?
It is a shortening of "Asynchronous", which means "occurring independently of the main program flow". Your main program thread will not wait for the AsyncHttpClient to complete its request before continuing. That's why your getResponse() method return immediately.
You should design your app to operate on event-driven programming principles; this means, in your case, that you would spawn whatever process or method you need to handle the response from the onSuccess() interface method.
So, you probably won't be returning anything from getResponse(). You can make it void. The AsyncHttpResponseHandler() you're instantiating and passing to the get() method is an interface which the library will call when certain events take place—that is, when the GET request succeeds or fails.
Finally, you will have to show your data somehow. I'm assuming it is in a ListView? If so, you will need to notify the ListView that its data has changed (or possibly recreate the adapter with new data). See this question. Also, I'm not sure but you may have to use runOnUIThread() to update your views, since this is running on a different thread.
I have the following json formatted string that is returned from the web service:
{"Success":false,"Message":"This version is not supported"}
I am using the following code to invoke the web service:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://mywebsite/check/getcompatibilityinfo", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
}
});
The response contains the json string now I need to access the Success and the Message property. Is there any simple way to do it without using complicated third party libraries?
The JSONObject class is already available in your Android codebase (no 3rd party dependencies). Since your example uses normal (simple) JSON, you can use:
try {
JSONObject responseJSON = new JSONObject(response);
} catch (JSONException e) {
e.printStackTrace();
}
boolean success = responseJSON.getBoolean("Success");
String message = responseJSON.getString("Message");