My actual question is down towards the bottom of the page, and may not require you to look at all of my code.
So I think I want to employ the Command Pattern in my Android application. I have a class HttpRequestHandler
which extends AsyncTask
and thus has the doInBackground
and onPostExecute
methods. HttpRequestHandler
takes a URL, and an HttpRequest type as parameters.
What I want to do is pass a method (in the form of an interface) to the HttpRequestHandler
so that in the onPostExecute
I can invoke that method and have it display the result gotten from the Http request in the given textview. This way I don't have to use a giant switch(case)
in my onPostExecute
I need some help with the execution though. In this case, I have two separate classes that implement Command.
public interface Command{
public void execute(JSONObject json);
}
public class DisplayResult implements Command{
public TextView textview;
public DisplayResult(TextView textview){
this.textview = textview;
}
@Override
public void execute(JSONObject output){
textview.setText(output.getString("mystring")
}
}
public class ConfirmPost implements Command{
public ConfirmPost(){
}
@Override
public void execute(JSONObject output){
Log.d("Success! ","POST successfull");
}
}
And the two calls to HTTPRequestHandler
, one passing a DisplayResult
and one passing a ConfirmPost
class.
public static void
TextView mytextview = (TextView) findViewById(R.id.mytextview);
new HttpRequestHandler(new DisplayResult(mytextview)).execute("myurl","GET");
new HttpRequestHandler(new ConfirmPost()).execute("myurl","POST");
Now it's in my HttpRequestHandler
where I'm having the problem.
public class HttpRequestHandler extends AsyncTask<String, String, String>{
Command presenter;
Public HttpRequestHandler(Object presenter){
this.presenter = (Command) presenter;
}
Public String doInBackground(String... uri){
...
}
Public onPostExecute(String result){
presentation = new JSONObject(result);
presenter.execute();
}
Using Object as an argument type seems to me, simply by feeling, not to be best practice. I've never seen anyone use it like this, and the idea of having to cast the given object as Command
rubs me the wrong way. Is there some way I can just make the class sort of trust that I'm giving it a Command object?
This is my first time using the Command Pattern, and I don't yet fully understand it. Be gentle.
UPDATE
It looks like I want to be using Generics here. I still don't really know how to execute that in a best practice manner though. What I have now is:
Command presenter;
public <Command> HttpRequestHandler(Command presenter){
this.presenter = (com.example.myproject.Command) presenter;
//ugly!
}
And this works just fine I can seemingly pass it any old implementation of Command
, I just can't seem to find any references online which have the same syntax or functionality. I've heard some mention of the factory pattern, but I have a feeling the Command Pattern doesn't rely on another pattern to be fully functional like this. Any direction would be appreciated.
Indeed it is a matter for Generics. Using Bounded Type Parameters and by having T
extend Command
, I can ensure that my parameter will be a subclass (in this case implementation) of Command
The HttpRequestHandler
should now look something like this
public class HttpRequestHandler extends AsyncTask<String, String, String>{
Command presenter;
public <T extends Command> HttpRequestHandler(T presenter){
this.presenter = presenter;
}
presenter.execute("Success!");
}
No horrendous casting necessary.