Issue
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 ?
Solution
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.
Answered By - biddulph.r
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.