Android Async Tsk not Executing Properly - java

I just want to wait in a splash screen until my JSON is processing, but that is not happening. TheonPostExecute() method is executed just after doinbackground(). There is no time to load the whole JSON.
Here is my code. I am getting List size zero first then JSON will start to load.
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
datalist = new ArrayList<>();
Log.e("entering","Enter Inside");
try{
JsonArrayRequest billionaireReq =
new JsonArrayRequest(new ApiURLs().getAll_movies_url()
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("response", "Response" + response);
//Initialize Gson obj to process jason response
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
// assigning data in model class, we initializing this class as a array type
// because the response is in array format
HomeModel[] getResult = gson.fromJson(response.toString(), HomeModel[].class);
// this loop help us in fetching all the records of model class
for (int i = 0; i < getResult.length; i++) {
Log.e("response", "Model Values" + getResult[i].toString());
//datalist.add(getResult[i]);
datalist.add(getResult[i]);
}
//GlobalData.setGlobal_movie_list(datalist);
Log.e("DataLoded","Record Added");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Request","Error" + error);
}
});
//This is a queue which is used by Volley to lineup requests
AppController.getInstance().addToRequestQueue(billionaireReq);
}
catch (Exception e){
Log.e("Error","Error"+e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("Data","DataSize"+datalist.size());
}
}

Related

How to access response value out of OnResponse method?

I want to see my array list in my logcat but when I run my app in logcat it shows that size of my array list is zero and there is no elements in it
this is my activity
public class Tmp2 extends AppCompatActivity {
public RequestQueue queue;
static ArrayList<Question> array_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tmp2);
array_list = new ArrayList<>();
queue= AppController.getInstance(this).getRequestQueue();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
"https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json",
(JSONArray) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i=0;i<response.length();i++) {
try {
Question question = new Question();
question.setAnswer(response.getJSONArray(i).get(0).toString());
question.setAnswertrue((Boolean) response.getJSONArray(i).get(1));
array_list.add(question);
} catch (JSONException e) {
e.printStackTrace();
}
}Log.d("wakwash","array "+array_list.size());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Log.d("json","array "+array_list.size());
queue.add(jsonArrayRequest);
Log.d("json","array "+array_list);
}
}
Logcat:
2020-10-25 00:32:43.548 18576-18576/com.example.practice D/json: array 0
2020-10-25 00:32:43.548 18576-18576/com.example.practice D/json: array []
its showing that size of my array is zero and there is no element it but when i use this log in onResonse it gives sizeand elements both. How can I access my array list out of the response
This is because you are logging your array size at wrong place even before you're getting the response, you are making a call which is asynchronous but the log that you've written is executed in synchronous manner that will always be empty.
Log your data when your response is received i.e in onResponse callback.
public class Tmp2 extends AppCompatActivity {
public RequestQueue queue;
static ArrayList<Question> array_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tmp2);
array_list = new ArrayList<>();
queue= AppController.getInstance(this).getRequestQueue();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
"https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json",
(JSONArray) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i=0;i<response.length();i++) {
try {
Question question = new Question();
question.setAnswer(response.getJSONArray(i).get(0).toString());
question.setAnswertrue((Boolean) response.getJSONArray(i).get(1));
array_list.add(question);
} catch (JSONException e) {
e.printStackTrace();
}
}Log.d("wakwash","array "+array_list.size());
// Log it over here
Log.d("json","array "+array_list.size());
Log.d("json","array "+array_list);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Log removed from here
queue.add(jsonArrayRequest);
}
}
You have to do your work after the response is received rather than doing it outside of the response scope, You can also make a callback for your response.

How to store response in a variable in Volley?

I Want to Store the response of Volley in a Public variable but when I Toast it out the volley request that returns null
public JSONArray array ;
String URL = "http://192.168.1.104/json.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
array = new JSONArray();
JsonArrayRequest request = new JsonArrayRequest( URL,new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
array = response;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(this).add(request);
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
As people have said, calling the Toast initiation within onResponse() works, but the best way to handle this is to create a small listener interface or method that is called in onResponse and implemented where you need it.
I'd also strongly suggest only passing the data you need and saving that in a model class, rather than just saving the response outright.
a very simple example would be
String URL = "http://192.168.1.104/json.php";
// make sure your class implements this
public interface ResponseListener {
public gotResponse(JSONArray array);
}
// implementation of ResponseListener
public gotResponse(JSONArray array) {
// eventually do more with this data
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
ResponseListener listener = this;
JsonArrayRequest request = new JsonArrayRequest( URL,new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
listener.gotResponse(response);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(this).add(request);
One way could be moving the line:
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
exactly to the line after: array = response;

How try call (recconnect) Json?

pDialog = new ProgressDialog(NewItemList.this);
pDialog.setMessage("Connect...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
jsoncall();
}
public void jsoncall() {
ArrayRequest = new JsonArrayRequest(URL_JSON, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSONObject jsonObject = null;
String temp;
pDialog.dismiss();
Loading_items.Load_list(NewItemList.this,response.length());
for (int i = 0 ; i<response.length();i++) {
try {
jsonObject = response.getJSONObject(i);
BaseItems items_info = new BaseItems();
items_info.setName(jsonObject.getString("name"));
CheckList.add(items_info);
Loading_items.AddItemOne();
}
catch (JSONException e) {
e.printStackTrace();
}
}
setRvadapter(CheckList);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(NewItemList.this);
requestQueue.add(ArrayRequest);
}
If the Internet stable - json works = everything well;
If to start without the Internet - pDialog isn't switched off = everything well;
If to start without the Internet, to cause jsoncall (); and to include the Internet - onResponse isn't carried out and I don't receive json = BAD :(;
How can I try to reconnect json?
enter image description here
I have solved so:
1) I have created a class of check of the Internet
2) I cause jsoncall () here so:
Thread myThready = new Thread(new Runnable()
{
public void run()
{
while (!TryConnectionInternet.TryConnectionInternet(NewItemList.this)){}
jsoncall();
}
});
myThready.start();

How to reuse / recycle downloaded JSON data from an AsyncTask on Android without redownloading it

Scenario: in the onCreate function I'm executing the AsyncTask, and in that class is where I'm pulling my json data. Then, based on a large-scoped variable, I'm decided which view to produce (default is 'all'). When an item in the ActionBar is pressed, the large-scoped variable is set differently, and a new instance of the AsyncTask is being created, there-in producing a different view.
Goal: Instead of pulling the json data each time a new view is selected, I want to use the same json data that was originally pulled. New json data can be retrieved when the 'refresh' option is selected, however.
I've tried several methods to solve this but I'm kind of new to Android programming and I haven't been able to get around this. Any suggestions would be appreciated. Some of the code is posted below.
** eventual solution [code does not reflect yet]**
I didn't really find the solution I was looking for from peers. As I figured, I didn't need a new library or need to cache my data (though maybe these will be helpful later on), rather what I needed was to re-organize my code. What ended up working for me, was that once I obtained my JSON data from my AsyncTask, I called a function in my MainActivity that then stored the JSON string into a variable.
public void onCreate(Bundle savedInstanceState){
....
new GetContacts().execute();
}
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.action_refresh:
new GetContacts().execute();
case R.id.action_all:
view_option = 1;
new GetContacts().execute();
case R.id.action_open:
view_option = 2;
new GetContacts().execute();
}
}
...
private class GetContacts extends AsyncTask<Void, Void, Void>{
String jsonStr = "";
protected void onPreExecute() { ... }
protected Void doInBackground(Void... arg0) {
ServiceHandler sh = new ServiceHandler();
jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
...
if (view_option.equals(1))
view_all(jsonStr);
else if (view_option.equals(2)){
view_open(jsonStr);
}
protected void view_all(String jsonStr){
// uses json data
....
}
protected void view_open(String jsonStr){
// uses json data
....
}
protected void onPostExecute(Void result) { ... }
}
I suggest you use Volley library for this. Starting from good tutorials here
Then, sample code for caching Json, you can refer the following:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(0, mUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
mTextView.setText(response.toString(5));
} catch (JSONException e) {
mTextView.setText(e.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null) {
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString), cacheEntry);
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected void deliverResponse(JSONObject response) {
super.deliverResponse(response);
}
#Override
public void deliverError(VolleyError error) {
super.deliverError(error);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
};
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
Happy coding and goodluck!

Getting null pointer exception on getting Async Task JSON using Android

I'm getting a NullPointerException when I try to request a JSON with AsyncTask. I'm using loopj and AsyncTask
Here's my code:
String str = null;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new TheTask().execute();
}
class TheTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
try{
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Authorization", "Token token=Wa5sfwP3ku7c15qkZTsd**");
client.get("http://*********.com/api/v1/***", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
str = response;
Log.v("==========RESULT==========", response);
}
});
} catch(Exception e){
Log.v("========== ERROR ==========", e.toString());
}
return str;
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.textView1);
txt.setText("Result: " + result);
}
}
}
You are doing it wrong.
In your doInBackground() method you should use synchronous methods, and you are using asynchronous:
client.get("http://*********.com/api/v1/***", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
str = response;
Log.v("==========RESULT==========", response);
}
That's why your doInBackground() returns null, and you are trying to deal with null in onPostExecute()
You should use methods from class SyncHttpClient from Loopj-Async library.

Categories