Here is my code:-
Goals.java class
public class Goals extends AppCompatActivity{
private ArrayList<Goal> result;
private RecyclerView.Adapter adapter;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Goal> dataFromServer;
private Toolbar toolbar;
//This is for back button
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
startActivity(new Intent(this, MainActivity.class));
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.goal_list);
recyclerView=(RecyclerView) findViewById(R.id.goal_recycler_view);
toolbar=(Toolbar) findViewById(R.id.toolbar);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
setSupportActionBar(toolbar);
//FOr back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
//fetch goal list from server and also its related action
getData();
//Send Data to GoalAdaptor
showData();
}
private void showData() {
Log.i("Show Date","Enter");
System.out.println("Result Array List"+result.toString());
adapter=new goalAdaptor(this, result);
recyclerView.setAdapter(adapter);
}
private void getData() {
result=new ArrayList<>();
DownloadPlansFromServer server= new DownloadPlansFromServer();
server.execute();
}
class DownloadPlansFromServer extends AsyncTask<Void,Void,Boolean>
{
private ProgressDialog progressDialog;
Boolean planActive=false;
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//UI Element
progressDialog = new ProgressDialog(Goals.this);
progressDialog.setMessage("Downloading Plans Data..");
progressDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
try {
System.out.println("Inside the response");
// Parsing json object response
// response will be a json object
System.out.println("Output is "+response.toString());
//Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
planActive=response.getBoolean("success");
if (planActive)
{
JSONArray plansArray=response.getJSONArray("response");
//get Plans Details
for (int p=0;p<plansArray.length();p++)
{
JSONObject plan=plansArray.getJSONObject(p);
//get Goals Details
JSONObject planGoals=plan.getJSONObject("goal");
Goal goal=new Goal();
goal.setGoal_name("Goal Name:- "+planGoals.getString("goal_name"));
Log.i("Goal Name is",planGoals.getString("goal_name"));
JSONObject currentValue=planGoals.getJSONObject("current_value");
JSONObject targetValue=planGoals.getJSONObject("target_value");
//Get the values parameter
ArrayList<String> parameterList=getTheParameter(planGoals.getString("goal_id"));
if (parameterList.isEmpty())
{
System.out.println("Problem WHile Processing the parameter ");
}
else
{
String goalDescription="Reduce the value from";
StringBuilder currentStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
currentStringBuilder.append(currentValue.getString(parameterList.get(k))+"/");
}
StringBuilder targetStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
targetStringBuilder.append(targetValue.getString(parameterList.get(k))+"/");
}
goal.setGoal_description(goalDescription+currentStringBuilder.toString()+" to "+ targetStringBuilder.toString());
}
//Add the result to the array
result.add(goal);
}
}
}
catch (JSONException k)
{
Log.i("On Response",k.getMessage());
k.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
String plan_url=Constants.url+"plan";
JsonObjectHeader customRequest=new JsonObjectHeader(plan_url,null, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
System.out.println("After custom Request");
planActive=true;
}catch (Exception e)
{
e.printStackTrace();
}
return planActive;
}
protected void onPostExecute(Boolean unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
progressDialog.dismiss();
if (unused)
{
Log.i("Get Plan","Yes");
//showData();
}
else
Toast.makeText(getApplicationContext(),"No Plans Found",Toast.LENGTH_LONG).show();
}
}
private ArrayList<String> getTheParameter(String goal_id) {
ArrayList<String> arrayList=new ArrayList<>();
if (goal_id.equals("bp"))
{
arrayList.add("systolic");
arrayList.add("diastolic");
return arrayList;
}
else
{
arrayList.add(null);
return arrayList;
}
}
}
The problem is:- Before getting the response from server, the onPostExecute() function executed. So I will get empty result arraylist.
JsonObjectHeader class is the basic volley class to fetch data from server.
No need to use async task while you want network call by using any third party library. because the volly create its own thread for network call.
If you are using volley
library then remove AsyncTask
and write this code in simple method
try {
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
try {
System.out.println("Inside the response");
// Parsing json object response
// response will be a json object
System.out.println("Output is "+response.toString());
//Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
planActive=response.getBoolean("success");
if (planActive)
{
JSONArray plansArray=response.getJSONArray("response");
//get Plans Details
for (int p=0;p<plansArray.length();p++)
{
JSONObject plan=plansArray.getJSONObject(p);
//get Goals Details
JSONObject planGoals=plan.getJSONObject("goal");
Goal goal=new Goal();
goal.setGoal_name("Goal Name:- "+planGoals.getString("goal_name"));
Log.i("Goal Name is",planGoals.getString("goal_name"));
JSONObject currentValue=planGoals.getJSONObject("current_value");
JSONObject targetValue=planGoals.getJSONObject("target_value");
//Get the values parameter
ArrayList<String> parameterList=getTheParameter(planGoals.getString("goal_id"));
if (parameterList.isEmpty())
{
System.out.println("Problem WHile Processing the parameter ");
}
else
{
String goalDescription="Reduce the value from";
StringBuilder currentStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
currentStringBuilder.append(currentValue.getString(parameterList.get(k))+"/");
}
StringBuilder targetStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
targetStringBuilder.append(targetValue.getString(parameterList.get(k))+"/");
}
goal.setGoal_description(goalDescription+currentStringBuilder.toString()+" to "+ targetStringBuilder.toString());
}
//Add the result to the array
result.add(goal);
}
}
}
catch (JSONException k)
{
Log.i("On Response",k.getMessage());
k.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
String plan_url=Constants.url+"plan";
JsonObjectHeader customRequest=new JsonObjectHeader(plan_url,null, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
because in volley
you can get response in onResponse
so add onPostExecute
inside this
Your issue is that you are creating an additional thread in your onBackground(Void...)
.
Your code sees:
You need to use a blocking method from the Volley system. This answer explains it.
RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, future, future)
volleyRequestQueue.add(request);
try {
JSONObject response = future.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
It's not your postExecute it's your
showData();
is executed before
getData();
is complete. Ideally move your showData code to your postExecute and you will get your results as expected.
Remove the AsyncTask.
Move all code from doInBackgroud in a normal function.
Call showSata() in onResponse().
I think you should read articles where is a good explanation why you should not have to use AsyncTask. My suggestion is start using Retrofit (for working with Http) + You do not have to parse JSON on your own, you can use @SerializedName annotation in your Response object
Here's a tutorial demonstrates how to fetch data from server and fill recycle view
Here is my code for signing in
Call<LoginResponse> call = retrofit.create(ComeAroundAPIInterface.class).signin(data);
call.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) {
onLoginSuccess();
sharedPreferences = getSharedPreferences(LOGIN_COOKIE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("LOGIN",true);
editor.commit();
progressDialog.dismiss();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("user", (LoginResponse)response.body());
startActivity(intent);
finish();
} else {
progressDialog.cancel();
onLoginFailed();
Converter<ResponseBody, APIError> converter = retrofit.responseBodyConverter(APIError.class, new Annotation[0]);
APIError error = new APIError();
try {error = converter.convert(response.errorBody());} catch (IOException e) {}
Toast.makeText(getBaseContext(),error.message(),Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
onLoginFailed();
Log.e("Login", t.toString());
}
});
and here is my Response class with @SerializedName annotation
public class LoginResponse implements Parcelable{
@SerializedName("id")
private String id;
@SerializedName("username")
private String username;
@SerializedName("email")
private String email;
@SerializedName("name")
private String name;
@SerializedName("sirname")
private String sirname;
//getters
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.