I'm doing an app that access a Web Service and with the JSON I get from it I create an object and use it in my code. Even though my app is working I don't know it is well written and flawless.
I'll explain what I have then put some Sample codes to demonstrate... First of all I created an Activity with a EditText and a Button, where the user will type a code and click in the button to access my database and check if it exists. The main is here: In my button.OnClickListener I check if the EditText has something on it and if I have internet connection <- (I've never had any problem on this) and after that I call my class RestClient that is extended from AsyncTask, that access the WebService in background and get a object from it. And only after this I will get the result from this RestClient. My solution was to start a new AsyncTask that waits my RestClient and then start the process to get the object.
here is the sample of my code my restClient that Return an Generic Object from my webservice:
public class RestClient<t> extends AsyncTask<String, String, String> {
private Class<t> tClass;
private t ObjReturn;
public RestClient(Class<t> tClass)
{
this.tClass = tClass;
}
public Object getObjectResponse(){
return ObjetoDeRetorno;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... OnlyTheURL) {
String urlString = OnlyTheURL[0];
String error = null;
WebApiDeRetorno = new WebApiRetorno();
try {
Log.i("RestClient","Starting connection");
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
String result = convertStreamToString(connection.getInputStream());
connection.disconnect();
JSONObject jsonObject = new JSONObject(result);
String obj = jsonObject.get("returnObject").toString();
Gson gson = new Gson();
ObjReturn = gson.fromJson(obj, tClass);
} catch (IOException | JSONException e) {
e.printStackTrace();
return error;
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
my buttom function:
buttonConfirmar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
restClient = new RestClient<>(MyObject.class);
restClient.execute(getString(R.string.WebServiceURL));
new WhenWebServiceConnectionFinished().execute();
}
});
The other AsyncTask Class that is executed AFTER RestClient and needs to Wait it finish:
private class WhenWebServiceConnectionFinished extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... params) {
//THIS IS WHAT I DON'T KNOW IF IT'S OK TO DO:
do {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (restClient.getStatus() != AsyncTask.Status.FINISHED);
//WAITING THE restClient.getStatus CHANGE TO FINISHED WITH Thread.sleepS.
if (checkWebApiRetorno()) {
objectReturnFromWebApi = (MyObject) restClient.getObjectResponse();
Intent intent = new Intent(thisActivity, NewActivity.class);
startActivity(intent);
finish();
return true;
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
if (progressDialog.isShowing())
progressDialog.dismiss();
if (!success)
dialogBuilder.create().show();
super.onPostExecute(success);
}
}
Add callback to first AsyncTask
and run second only after onPostExecute
fired by first AsyncTask
Something like
public interface AsyncFinishedCallback{
public void onAsyncFinished();
}
and in first AsyncTask
do constructor like this
public RestClient(Class<t> tClass, AsyncFinishedCallback callback)
{
this.tClass = tClass;
this.callback = callback; //declare it somewhere as a field
}
and than
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(callback!=null)
callback.onAsyncFinished();
}
}
Than in button function
buttonConfirmar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
restClient = new RestClient<>(MyObject.class, new AsyncFinishedCallback(){
@Override
public void onAsyncFinished(){
new WhenWebServiceConnectionFinished().execute();
}
});
restClient.execute(getString(R.string.WebServiceURL));
try this: start another task when u get result from first Async task
use AsyncTask<String, String, Boolean>
public class RestClient<t> extends AsyncTask<String, String, Boolean> {
private Class<t> tClass;
private t ObjReturn;
public RestClient(Class<t> tClass)
{
this.tClass = tClass;
}
public Object getObjectResponse(){
return ObjetoDeRetorno;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... OnlyTheURL) {
String urlString = OnlyTheURL[0];
String error = null;
WebApiDeRetorno = new WebApiRetorno();
try {
Log.i("RestClient","Starting connection");
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
String result = convertStreamToString(connection.getInputStream());
connection.disconnect();
JSONObject jsonObject = new JSONObject(result);
String obj = jsonObject.get("returnObject").toString();
Gson gson = new Gson();
ObjReturn = gson.fromJson(obj, tClass);
return true;
} catch (IOException | JSONException e) {
e.printStackTrace();
return false;;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
//success occurs task finish
new WhenWebServiceConnectionFinished().execute();
} else {
//error occurs
}
}
}
}
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.