I'm using this code for sending data to server , but when i want to parser response data on volley onResponse method , my UI freezing .
JsonObjectRequest req = new JsonObjectRequest(Method.GET, url, null, new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response)
{
parseFromJsonObject(response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
}
});
RequestHelper.getInstance().addToRequestQueue(req, this);
And it's parser method
public boolean parseFromJsonObject(JSONObject response)
{
boolean validResponse = super.isValidResponse(response);
try
{
if(response.has("keywords"))
{
JSONObject keywords = response.getJSONObject("keywords");
Iterator<?> langIterator = keywords.keys();
ArrayList<LanguagesStorage> languagesStorageArray = new ArrayList<LanguagesStorage>();
while(langIterator.hasNext())
{
String lang = (String) langIterator.next();
JSONObject langValues = keywords.getJSONObject(lang);
Iterator<?> valueIterator = langValues.keys();
while(valueIterator.hasNext())
{
String key = (String) valueIterator.next();
String value = (String) langValues.getString(key);
LanguagesStorage languagesStorage = new LanguagesStorage();
languagesStorage.setKey(key);
languagesStorage.setLang(lang);
languagesStorage.setValue(value);
languagesStorageArray.add(languagesStorage);
}
}
if(languagesStorageArray.size() > 0)
{
LanguageAdapter languageAdapter = new LanguageAdapter();
languageAdapter.insert(languagesStorageArray, true);
}
}
return lastParsingStatus = true;
}
catch (JSONException e)
{
RLog.error("Parsing error in keyword Parser " + e);
return lastParsingStatus = false;
}
}
What is the issue ? Why my UI thread freezing?
Volley onResponce work inside the UI thread
I recommend you to do parsing inside a separate thread.
In your parseFromJsonObject method, try to create a new Thread and inside that thread execute your parsing data.
Related
I know this question has been asked a few times and i have tried all the solutions however, nothing seems to work. My method:
public static LocationGeoData getLocationGeoData(Location location){
RequestQueue requestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
Date dateNow = new Date();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy.MM.dd");
String url = "MYCORRECTURL";
Log.d("geoData", "In getGeoData " + url); // this is called and logs
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("geoData", "inside the response");// this never gets called
try {
JSONObject jsonObject = response.getJSONObject("data");
for(int i = 0; i <jsonObject.length(); i++){
JSONObject heading = jsonObject;
if(heading.getString("field-value").equals("field-value")){
JSONObject totIntensity = heading.getJSONObject("total-intensity");
JSONObject declination = heading.getJSONObject("declination");
JSONObject inclination = heading.getJSONObject("inclination");
int totalIntensity = totIntensity.getInt("value");
double declinationValue = declination.getDouble("value");
double inclinationValue = inclination.getDouble("value");
locationGeoData = new LocationGeoData(totalIntensity, declinationValue, inclinationValue);
}
}
} catch (JSONException e) {
Log.d("geoData", "Error recorded");//never called
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("geoData", "Error recorded");// never called
}
});
requestQueue.add(request);
return locationGeoData;
}
The second Log message inside the response never gets called, i get no error messages, my url works and i can see the JsonOBject in the browser when tested, but the response is never called in my method. Can anyone advise me what i am doing wrong?
I want to parse a single url from my remote json file. I have a Button code in onCreate and I want to parse url from my json object to my DynamicButton.
private void parseJSON() {
String url = https://www.example.com/data.json
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("MyDynamicUrl");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String myDynamicLink = hit.getString("Link");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
I have this button in onCreate and Now I want to parse myDynamicLink to this button. I am getting Error "Can not resolve symbol 'MyDynamicLink' "
DLbtn = findViewById(R.id.DynamicLinkButton);
DLbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url = myDynamicLink;
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
My json file structure
{
"MyDynamicUrl": [
{"Link":"https://www.myDynamicUrl.com"}
]}
You should define myDynamicLink as a field outside of the method and then set a value to it:
private String myDynamicLink;
private void parseJSON() {
...
myDynamicLink = hit.getString("Link");
...
}
Also note, that the request is made asynchronously (on another thread),
it means that your button may be already initialized and you can click it, but possibly you may still not receive a response.
In addition, you may start using a library for converting JSON objects to Java objects, such as Gson, it will let you much easily parse the JSON.
this is the api response i ma accessing the json object and setting the textview of uuid in text view but nothing happen
please suggest code for accessing json object from api response
{
"success":true,
"data {
"serial_key_id":"75",
"order_id":"0",
"product_id":"0",
"serial_key":"WURYFO",
"valid_till":null,
"limit":"0",
"uuid":"",
"used":false
}
}
private void jsonobject() {
String url = "http://mylocalpay.com/?serial_key_api=1&coupon=WURYFO";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("msg", "response" + response);
try {
JSONObject success = response.getJSONObject("success");
JSONObject data = response.getJSONObject("data");
String serial_key_id = data.getString("serial_key_id");
String order_id = data.getString("order_id");
String product_id = data.getString("product_id");
String serial_key = data.getString("serial_key");
String limit = data.getString("limit");
String uuid = data.getString("uuid");
boolean used = data.getBoolean("used");
JSONObject valid_till = data.getJSONObject("valid_till");
textView.setText(uuid);
System.out.println(serial_key);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
}
}
You need to parse this JSON into a java object. You could write your own code to do this (which is a very large undertaking) or you could use Googles GSON library.
GSON GitHub page
You can use this library as so
Gson gson = new Gson();
String jsonInString = "{'serial_key_id' : '75'}";
YourClass yourClass = gson.fromJson(jsonInString, YourClass.class);
Question1: How to get response value in onResponse function.
Question2: I create cauHoiArrayList. when I check and get cauHoiArrayList values in onResponse function => it worked. But if I check and get cauHoiArrayList values in GETDATA function ==> it did not work. How to I get cauHoiArrayList values.
Thanks you,
This is my code details:
public void GetCauHoi(String url) {
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(
Request.Method.POST,
url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response);
cauHoiArrayList = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
_id = object.getInt("_ID");
cauhoi = object.getString("CauHoi");
tenmh = object.getString("TenMH");
tenmonhoc = object.getString("TenMonHoc");
dapan_a = object.getString("DapAn_A");
dapan_b = object.getString("DapAn_B");
dapan_c = object.getString("DapAn_C");
dapan_d = object.getString("DapAn_D");
dapandung = object.getString("DapAnDung");
hinhanh = object.getString("HinhAnh");
dokho = object.getInt("DoKho");
cauHoiArrayList.add(new CauHoi(_id, cauhoi, tenmh, tenmonhoc, dapan_a, dapan_b, dapan_c, dapan_d, dapandung, hinhanh, dokho));
}
Log.d("tag",""+cauHoiArrayList.get(0).getCauHoi());
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ScreenSlideActivity.this, ""+error, Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("laytenmonhocc", "" + laytenmonhoc);
params.put("laydokhoc", "" + laydokho);
return params;
}
};
requestQueue.add(stringRequest);
}
public ArrayList<CauHoi> GETDATA (){
return cauHoiArrayList;
}
Volley requests are asynchronous. You must be calling GETDATA by time when response is not arrived yet. You need to sure call GETGATA when you have response. Only OnResponse method is guarantee that response is present.
I know there are some identical questions but I just couldn't figure out what I'm doing wrong.
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
new JsonHandler().execute(this, collection, gridArray, customGridAdapter);
...
}
}
So in my main activity I need to query an API which gives back JSON and I have to process that to build my database.
Then in doInBackground() I call getAllCards() which gets the first JSON. Because the JSON includes URLs for more JSON requests, I have a few methods each querying a more detailed JSON.
public final class JsonHandler extends AsyncTask {
private final String urlCards = "https://api.gwentapi.com/v0/cards/";
private final String urlSpecificCard = "https://api.gwentapi.com/v0/cards/:id";
private Context context;
private Collection collection;
private ArrayList<Card> gridArray;
private CustomGridViewAdapter customGridAdapter;
public JsonHandler(Context context, Collection collection, ArrayList<Card> gridArray, CustomGridViewAdapter customGridAdapter){
this.context = context;
this.collection = collection;
this.gridArray = gridArray;
this.customGridAdapter = customGridAdapter;
}
public JsonHandler(){
this.context = null;
this.collection = null;
this.gridArray = null;
this.customGridAdapter = null;
}
private void getAllCards() throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, urlCards, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
generateCollection(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void getSpecificCard(final String cardURL) throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, cardURL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
processCard(response, collection);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void generateCollection(JSONObject response) throws RuntimeException {
try {
JSONArray array = response.getJSONArray("results");
for(int i = 0; i < array.length();i++){
JSONObject object = array.getJSONObject(i);
String cardURL = object.getString("href");
getSpecificCard(cardURL);
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private void processCard(JSONObject response, Collection collection){
try {
String id = response.getString("id");
EnumFaction faction = EnumFaction.valueOf(response.getJSONObject("faction").getString("name").toUpperCase());
EnumType type = null;
EnumRarity rarity = null;
EnumLane lane = null;
EnumLoyalty loyalty = null;
String name = response.getString("name");
String text = response.getString("text");
String imagePath = "https://api.gwentapi.com/media/\" + id + \"_small.png";
URL url = new URL(imagePath);
InputStream inputStream = url.openConnection().getInputStream();
Bitmap image = BitmapFactory.decodeStream(inputStream);
Card card = new Card(id, faction, type, rarity, lane, loyalty, name, text, null, imagePath, 0);
collection.addCard(card);
gridArray.add(card);
customGridAdapter.notifyDataSetChanged();
} catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
#Override
protected Object doInBackground(Object[] params) {
context = (Context) params[0];
collection = (Collection) params[1];
gridArray = (ArrayList<Card>) params[2];
customGridAdapter = (CustomGridViewAdapter) params[3];
getAllCards();
return null;
}
}
So now on to the problem:
When the programm reaches processCard() when I've gathered enough information, I get a NetworkOnMainThreadException when I create the InputStream.
I've tried so many different methods to get a Bitmap from my URL and different methods to do an asynchronous task - all leading to the same result.
If you could show me how to resolve this issue, I'd be sooo happy.
Edit: Since it got marked as duplicate: I AM USING ASYNCTASK! I have looked at many questions and tried what they did there, it doesn't work!
Not really familiar with how volley works but onResponse but be on the main thread so you need to start a new thread to make that call too