I want a helper class for http connection. I am able to write simple code to connect using HttpUrlConnection and Async task and it works well.
But I am confused how can I write a more generic reusable class HttpHelper.
I got this HttpHelper class from internet (It just does a simple get call, I will later extend it to deal with post calls with query parameters), but I am not able to figure out how to call/use this as is. I am confused with the callbacks and the generics.
If I want to make a http request using this call and expect String result, this is what I attempted and it is all with syntax errors.
HttpHelper<String> api = new HttpHelper<>();
api.get("www.google.com", new HttpHelper.Callback<String>{
#Override
String execute(String html){
}
#Override
void finish(String result){
}
});
Thanks for your help
K
you have to call your method like this:
HttpHelper<String> api = new HttpHelper<String>();
api.get("www.google.com", new HttpHelper.Callback<String>{
#Override
String execute(String html){
return html; // This line is very very important.
}
#Override
void finish(String result){
// Do whatever you wan to do with your server response.
}
});
And do check your imports which HttpHelper class your are importing.
This works for me . Happy Coding !!!
Related
I am new to android programming. I am using rest call from android to query result and based on the queried result I allow user to navigate from one screen/activity to another. I have around 7 activity page and on each page I perform several operations for that I use rest call.
The way I am invoking is using AsyncHttpClient
Ex.
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://serverurl:8080/path1/path2/path3", params, new AsyncHttpResponseHandler() {
//some code
}
The one problem which I am facing is if I have to modify the url I need to modify in all the activity page.
Is there a way from where I can modify once that can be used in every activity?
Is there a better way? Please let me know.
Use Retrofit
public interface GitHubService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
#GET("users/repos/{id}")
Call<Repo> getRepo(#Path("id") String id);
}
Any kind of url changes can be done in this interface
Initialization of retrofit with base url
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
Consuming Api
Call<List<Repo>> repos = service.listRepos("octocat");
repos.enqueue(new Callback<List<Repo>>() {
#Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
//Do something with response
}
#Override
public void onFailure(Call<List<String>> call, Throwable t) {
//handle failure
}
});
For more Retrofit
There are several ways to do API calls in your android application.
Using a library like Retrofit, you can perform API requests without any problems by using an interface.
You can also use the default Url connection that comes with Android to do all sorts of operations like GET and POST among others.
If you are worried about how to easily change the endpoint (url), you can write your code so that you pass in a string param to your methods that way, you don't hard code the value.
I am sure there are a lot more libraries out there and normally, it is a matter of choice and taste.
I hope this helps you as you try to solve your problem!
Just use a static variable.
public class YourClass {
public static final String URL = "http://www.example.com/abc";
public void performApiCall() {
AsyncHttpClient client = new AsyncHttpClient();
client.get(URL, params, new AsyncHttpResponseHandler() {
//some code
});
}
}
You can then use the URL string from other classes:
public class SomeOtherClass {
public void performSomeOtherApiCall() {
AsyncHttpClient client = new AsyncHttpClient();
client.get(YourClass.URL, params, new AsyncHttpResponseHandler() {
//some other code
});
}
}
I've got a basic setup using Robospice with Retrofit in a shell Android application making REST calls, parsing JSON response into a POJO and that I can then use to render in an Activity. I now want to use TLS only for transport security (not SSL). I've read that Retrofit with OkHttp can be used to achieve this but I don't know where to make the update in my code.
I have a basic interface:
public interface RandomAPI {
#GET("/users")
List<User> getUsers(#Path("owner") String owner, #Path("repo") String repo);
#GET("/users/{userid}")
User getUser(#Path("userid") int userID);
}
I have a Service:
public class RandomService extends RetrofitGsonSpiceService {
private final static String BASE_URL = "http://jsonplaceholder.typicode.com";
#Override
public void onCreate() {
super.onCreate();
addRetrofitInterface(RandomAPI.class);
}
#Override
protected String getServerUrl() {
return BASE_URL;
}
}
and finally a request:
public class RandomRequest extends RetrofitSpiceRequest<User, RandomAPI> {
private int userID;
public RandomRequest(int userID) {
super(User.class, RandomAPI.class);
this.userID = userID;
}
#Override
public User loadDataFromNetwork() throws Exception {
return getService().getUser(userID);
}
}
I'm guessing I need to update the Service but not really sure how. I really like the simplicity of this pattern so would like to keep it if possible. I can drop the OkHttp jars into the application but I don't know how to get at the actual implementation of the service, or how to add my custom one so that all requests use it.
Has any one had experience with this that could share some code snippets or point me to an example?
~~ EDIT ~~
Looking into the API for Robospice, looks like my request can just extend SpiceRequest, then within the loadFromNetwork() method I just do plain Retrofit and OkHTTP stuff. Is that the only way though? Thought there would be a way to set your own RestAdapter implementation in RetrofitSpiceService instead of just using the default.
So to do this is actually quite simple. Create a class which extends RetrofitGsonSpiceService and override the createRestAdapterBuilder() method.
e.g.
#Override
protected Builder createRestAdapterBuilder() {
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(SERVICE_URL)
.setRequestInterceptor(requestInterceptor);
return builder;
}
I am using approach, described in this question to add my specific header to HTTP get request. But I can't understand how I need to change my code to make interceptor to do his job. Currently I am using something like this:
#RestService
ImwizardClient imwizardClient;
//some code
return imwizardClient.getAllCategories();
where getAllCategories() is method, which makes get request. The request works correctly, but it doesn't add my custom header. So what do I need to change?
Is your Interceptor defined for your RestService class as documented here?
#Rest(interceptors = { HttpBasicAuthenticatorInterceptor.class })
public interface ImwizardClient {
// ... snipped
}
Alternatively, the workaround posted in this thread seems to work reliably. Just define a custom MessageConverter for your RestService class.
public class GsonWithHeadersConverter extends GsonHttpMessageConverter {
#Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
setHeaders(outputMessage); //My method to put the additional headers :)
super.writeInternal(o, outputMessage);
}
}
I am writing an app for android that connects to a server to get/post some xml data. I currently have a small class with static methods such as post(string URI, string body) and get() that wrap the httpclient calls to create a http post request and return the response. I am wondering if i should also have these method work in their own threads. Currently, i need to do a async task to call my Helper.post(..) method to connect to and get a request from a server. Is it better to just have the async stuff incorporated in the helper class to avoid having multiple repeated async tasks all across my app to just make post calls?
As a general principle it is best to wrap up repeated code so that you dont continually re-invent the wheel. Therefore if it is possible for you to wrap up the threading easily then it would be a good idea to do so.
This is not always very easy. Methods which get something from the network define want done with that data once it's been received. Usually you just return it. But if you're threading within the method then you have to push it somewhere. This leads to a lot of additional callbacks and you dont (in my experience) save much.
Rather than defining a bunch of static methods which do the threading for you, I would recommend you keep threading out of the static methods and define a bunch of abstract AsyncTasks instead. Each defines it's own doInBackground and leaves the onProgressUpdate and onPostExecute methods undefined. That way you get the best of both worlds - you re-use as much as possible (the doInBackground code) but are able to customize where the data is sent once received.
Example
Your static code:
public class MyStaticClass {
public static String getFoo( String name ) {
// use the network to get a string;
return "hello " + name; // Use your immagination.
}
}
An AsyncTask defined as public so that it can be re-used easily.
public class GetFooTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground( String... name ) {
return MyStaticClass.getFoo(name[0]);
}
}
Now to use it. Your static library or public async task could not have known what you need to do with the resulting string. So you tell it what to do with the result here:
public class MyActivity extends Activity {
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
// You've already defined how to get the data
// so using it requires only minimal code now.
GetFooTask titleTask = new GetFooTask() {
#Override
public void onPostExecute( String heading ) {
((TextView) findViewById(R.id.heading)).setText(heading);
}
};
titleTask.execute("John");
}
}
In this example you can use the GetFooTask in as many activities as you like, just tell it where to put the data each time.
If you really think you will never want to do two network tasks on the same thread then you can combine the static code and the "abstract" AsyncTask. But more often than not I find I want to fire several things to and from the network before I finally return a result. If I did the threading in the network static code I would end up firing 10 threads for one request... therefore I keep threading out the static code.
I'm trying to make an application that uses Asynctask. Particularly, I want to make different http petitions with different JSON in different activities without the activity being frozen while the communication is done.
At first I thought to use asynctask as a private inner class in those activities, but I saw that they share a lot of code. So I thought to make a single class and play with broadcast receivers as I need to monitorize when I receive the result of the http petition, and isn't good to interfere with activity directly in the onPostExecute while in a different class.
What I want to know is, what is more efficient and better practice. Make a class that has the shared code and extends asynctask, then doing inner classes for each activity that extends that one or make a single asynctask that sends broadcast and receive them with each activity when needed.
Excuse my poor english, if needed I'll try to specify more clearly.
Thanks in advance
Background
What I want to know is, what is more efficient and better practice. Make a class that has the shared code and extends asynctask, then doing inner classes for each activity that extends that one or make a single asynctask that sends broadcast and receive them with each activity when needed.
I'm unclear as to why these are your only two options. Create a single AsyncTask, such as JsonPetitionTask, then push a new JsonPetitionTask.Data object. This object would contain your URL, your JSON, and any other data you need.
Setting up the AsyncTask
Something like this:
public class JsonPetitionTask extends AsyncTask<JsonPetitionTask.Data, Integer, Boolean> {
protected Boolean doInBackground(JsonPetitionTask.Data... args) {
for (int i = 0; i < args.length; i++) {
JsonPetitionTask.Data data = args[i];
// Send your JSON; check for errors, and return false if needed.
if (isCancelled()) break;
}
return true;
}
protected void onProgressUpdate(Integer... progress) {
// Show progress?
}
protected void onPostExecute(Boolean result) {
// result is your success true/false.
}
public static class Data {
public String jsonContent;
public String petitionUrl;
public Data(String content, String url) {
jsonContent = content;
petitionUrl = url;
}
}
}
Calling the JsonPetitionTask
Then you can call it like so:
JsonPetitionTask.Data data = new JsonPetitionTask.Data(myJSON, myURL);
new JsonPetitionTask().execute(data);
And voilĂ , you've executed your AsyncTask using only one class with no receivers.
Implementing a callback
Now, if you want to register a callback (something to execute that is specific to the calling code), that's a bit trickier. If this is part of what you're looking for, I'll be glad to edit this post and explain it.
To add a callback, we can use the Runnable class to execute some code after the job is done.
Firstly, we need to add a new field in the Data inner class:
public Runnable callback;
Next, before we call execute(), we need to add a new callback to our data object.
data.callback = new Runnable() {
public void run() {
// Whatever code you want to run on completion.
}
};
Third, in the JsonPetitionTask class, we need a list of things to run:
private ArrayList<Runnable> mRunnables = new ArrayList<Runnable>();
Make sure, in each iteration of the doInBackground() loop, that you do mRunnables.add(data.callback);.
Lastly, in onPostExecute(), we need to call this:
protected void onPostExecute(Boolean result) {
for (Runnable r : mRunnables)
if (r != null) r.run();
}
I do realize I didn't send result to the Runnable, however I didn't feel like implementing a new Runnable type just to handle that. If you need this, I guess that's a bit of homework for you!
The way I found the best is just simply create public class that extends AsyncTask and then you just override onPostExecute function in every activity you use it.
Example:
MyDataTask dataTask = new MyDataTask() //you can add your parameters in class constructor
{
#Override
protected void onPostExecute(Object result) //replace Object with your result type
{
MyActivity.this.doStuff(result); //use result in current activity
}
};
you can also create some custom functions to set private variables in datatask
dataTask.AddParam("user", username);
dataTask.AddParam("pass", pass);
and then just execute it with your args...
dataTask.execute(myArgs);
I have used Async task class as single class. And for every Webservice call i have used unique IntentFilter to Broadcast response.
Put that Broadcast receiver in every class. You have perfect solution.
Its working well.