Well, I have an activity class with two background task (Async-Task) which have been defined in two separate classes like
public class GettingBeaconsList extends AsyncTask<String, String, String>
public class GettingAirports extends AsyncTask<String, String, String>
which are initialized and executed in MainClass
public class MainClass extends Activity implements DelegateTaskCompleted
{
int ServiceBoolean = 0;
public OnClickListener LoadingBeaconList = new OnClickListener()
{
public void onClick(View v)
{
ServiceBoolean =1;
new GettingBeaconsList (context,MainClass.this).execute();
}
}
public OnClickListener LoadingAirportList= new OnClickListener()
{
public void onClick(View v)
{
ServiceBoolean =2;
new GettingAirports(context,MainClass.this).execute();
}
}
@Override
public void JsonArrayLoaded(JSONArray result)
{
// bla bla or whatever here i write, does not matter
if(ServiceBoolean == 1) {
// Load activity 5
}
else if( ServiceBoolean == 2)
{
// Load activity 6
}
else if( ServiceBoolean==3 )
{
// display Toast or Alert Box or load Activity number 8
}
}
}
Now in above code MainClass.this is stored as Interface Reference in AsynTask SubClasses like this
private Context context = null;
private DelegateTaskCompleted delegate = null;
public GettingBeaconsList (Context context,DelegateTaskCompleted delegate)
{
this.context = context;
this.delegate = delegate;
}
// And constructor of second AsynTask is same as of First AsynTask Class
private Context context = null;
private DelegateTaskCompleted delegate = null;
public GettingAirports (Context context,DelegateTaskCompleted delegate)
{
this.context = context;
this.delegate = delegate;
}
onPostExecute of each AsynTask class or subclass, JSONArray is returned or passed back to the calling class, shown below. In this case calling class is MainClass but there are other activity classes which use same AsynTask Classes(GettingBeaconsList and GettingAirports)
protected void onPostExecute(String file_url)
{
pDialog.dismiss();
delegate.JsonArrayLoaded(gotNearestbeacons);
}
Now I have one method (JsonArrayLoaded) in MainClass to tackle two response coming from two different background task or services. I am using condition to figure out which service/class or AsynTask is executed.
But I am asking for the best way to tackle such scenario as if we have 5 or more background services in future and they just also return a JSON Array so do I need to make separate interfaces for each services ?
What should be object oriented way out to this case ?
Recommended solutionScheduling deferred work through WorkManager is the best way to handle tasks that don't need to run immediately but which ought to remain scheduled when the app closes or the device restarts.
It is used to provide total abstraction. That means all the methods in an interface are declared with an empty body and are public and all fields are public, static, and final by default. A class that implements an interface must implement all the methods declared in the interface.
This is the interface for callback
public interface CallbackReceiver {
public void receiveData(Object result);
}
Use Asynctask class as Abstract class
public abstract class JsonDataCallback extends AsyncTask<String, String, String> implements CallbackReceiver {
private ProgressDialog mProgressDialog;
Handler handler;
Runnable callback;
Activity activity;
public JsonDataCallback(Activity activity)
{
this.activity=activity;
mProgressDialog = new ProgressDialog(activity);
mProgressDialog.setMessage("Loading Please Wait.");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
}
public abstract void receiveData(Object object);
@Override
protected void onPreExecute() {
mProgressDialog =ProgressDialog.show(activity, "", "Please Wait",true,false);
super.onPreExecute();
}
@Override
protected String doInBackground(String... aurl) {
String results="";
// do stuff
return results;
}
@Override
protected void onPostExecute(String jsonData) {
if (mProgressDialog != null || mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
if(jsonData!=null)
{
receiveData(jsonData);
}
}
}
And in your code use it like this
String url = ipaddress + "/GrantAdvanceList;
JsonDataCallback callbackservice = new JsonDataCallback(yourActivity.this) {
@Override
public void receiveData(Object object) {
jsonRecordsData = (String)object;
//do stuff with call back data
}
};
callbackservice.execute(url, null, null);
You can reuse the code this way.
The most simplistic solution I can think of is to modify your DelegateTaskCompleted
interface so as it looks like this:
public interface DelegateTaskCompleted{
public void JsonArrayLoaded(AsyncTask<String, String, String> task,
JSONArray result);
}
Then your onPostExecute
will send itself back like below:
protected void onPostExecute(String file_url)
{
pDialog.dismiss();
delegate.JsonArrayLoaded(this, gotNearestbeacons);
}
Finally, in your MainClass
, you can have a conditional check based on the type of AsyncTask
:
@Override
public void JsonArrayLoaded(AsyncTask<String, String, String> task,
JSONArray result)
{
if(task instanceof GettingBeaconsList) {
// do stuff related to the beacon list
}
else if(task instanceof GettingAirports) {
// do airport list stuff
}
}
That way you can easily identify the AsyncTask
that sends through the response without having to track which it is, if one takes longer than the other etc.
Alternatively, have another class that extends AsyncTask
but adds an abstract variable for identification.
public class TrackableAsyncTask extends AsyncTask<String, String, String>{
public abstract int getId();
public static final int ID_AIRPORT = 1;
public static final int ID_BEACONS = 2;
... etc
}
Then have your Airport and Beacon AsycTasks
extend this instead. This will require them to implement the getId
method.
public class GettingAirports extends AsyncTask<String, String, String> {
public int getId(){
return ID_AIRPORT;
}
}
And then instead of doing a conditional if (task instanceof GettingAirports)
you can do a switch
statement like below:
switch(task.getId()){
case TrackableAsyncTask.ID_AIRPORT:
// run airport code
}
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With