One Class Pattern for All Web API calls - android

In my app I have a-lot of Web API calls which returns me JSON. I am trying to do this thing simple. I don't want to create AsyncTask in every fragment. I have tried many things but nothing give me the solution how to do this. I need one Class solution in which I call a method with a url argument and get result in calling fragment or activity. Can someone share best practice to do this?
I have tried otto library but It seems it don't fulfill my requirements.

Web communication should not be done in main thread, therefore, some kind of threading is necessary. I think AsyncTask is the easiest way. I suggest creating abstract class, implementing network-stuff, and leave parsing output for child classes. Something like this:
abstract class DownloadJSON extends AsyncTask<...>{
DownloadJSON(List<NameValuePair> httpParams){...}
JSONObject doInBackground(String... urls){... return mJSONObject}
abstract void onPostExecute(JSONObject json);
}
You may override doInBackground for further background parsing or just display contents in onPostExecute.

Please check the library called Retrofit. It turns your REST API into a Java interface and has asynchronous execution of requests. It even converts your JSON response into Java objects.

Related

Android - Passing complex interface to JobScheduler

I want to run a job using JobScheduler, and within that job I need to execute a method on a class which is an implementation of a specific interface, so it isn't a POJO or something like that which can easily be passed as a JSON string.
What I currently thought was to serialize that class to a file and then retrieve it later from within the JobService.
Is there any better way to do it?
Thank you.
You could use the build-in method setClipData(ClipData, int) - link, where you could apply deserialization of that object in the moment, when the Job will be triggered.

Where to attach the reference to a Retrofit adapter in Android?

I am referencing this post Where to keep Retrofit Adapter in Android App? but I am not allowed to comment there due to stackoverflow limitations [thank you stackoverflow for treating new users like kids].
Where does the Retrofit RestAdpater go when using Android? Can anybody please elaborate on #Jake Wharton 's answer of above post.
When I place the RestAdapter in my Activity, it will probably get GCed when the Activity is destroyed, so the Singleton loses its reference and needs to be recreated the next time (I assume).
Further, the first thing that I did for testing is exactly this and Android tells me I cannot do a network request on the Main thread. I understand that I can't do that, but I thought Retrofit would automatically create a separate thread for me.
Will I need to create an AsyncTask to host the RestAdapter? Or how exactly does this work for Android? Where is the adapter best instantiated? Which is the recommended point to attach the Retrofit reference?
So what #JakeWharton was saying is that the RestAdapter and the api interface instances should be created once. How you achieve that is pretty much an implementation details.
In a straight forward manner you could create a class which would hold a single instance to your RestAdapter. You would be responsible of making only a single instance of that class. You'd probably want to hold a reference to this class in your Application class. You could also approach this using the Singleton pattern
Here's a small class to get you started. I took this from a previous post which you can see here
public class RestApiDispencer {
private Map<String, Object> restApiInstances = new HashMap<String, Object>();
private RestAdapter restAdapter;
public RestApiDispencer(RestAdapter restAdapter) {
this.restAdapter = restAdapter;
}
public <T> T getRestApi(Class<T> clazz) {
T client = null;
if ((client = (T) restApiInstances.get(clazz.getCanonicalName())) != null) {
return client;
}
client = restAdapter.create(clazz);
restApiInstances.put(clazz.getCanonicalName(), client);
return client;
}
}
If you're familiar with dependency injection then that would be another way to go. Personally I prefer to use dependency injection when it comes to hiding implementation details from use.
Creating the RestAdapter directly into your Activity would not the way you'd want to go. Instead in your activity would want to get a reference to this RestApiDispencer class from above and have it return the instance of the rest api of your choise by providing its class like so.
MyClassApi myClassApi = restApiDispencer.getRestApi(MyClassApi.class);
There are other ways to achieve this but as I said it's up to you to decide which implementation fits best your needs.
As for Retrofit doing request on a separate thread, yes it does but you need to create your Api interfaces accordingly.
#GET(/some/rest/api/path)
Response getApiData() // Synchronous declaration as the Response is returned from the method.
#GET(/some/rest/api/path)
void getApiData(Callback<Response> callback); // Asynchronous as the Response is delivered in the callback.
#GET(/some/rest/api/path)
Observable<Response> getApiData(); // Asynchronous again but you'll need to read up on rx-java before using this.
Read on rx-java here
So if you do decide to create your rest api by using the asynchronous signature then you won't have to worry about threading when invoking your interface. If you use the synchronous signature then it's all up to you.

What is the purpose of adding parameters to an AsyncTask?

Sorry for being a newbie, I've looked everywhere and I just don't get it.
Asynctask needs 3 parameters; e.g.
but what is the point of these parameters?
I am trying to run a geocoder in a separate thread and I have this
private class GetCurrentCity extends AsyncTask<String, Void, Void>{
but I literally made those parameters up. I have no idea what I'm supposed to put there. I don't need a progress bar or anything to be transferred to the other thread except for the line of code that is already in doInBackground() . Then I need a string to be returned from that, and I am using onPostExecute(String returnedAddress) for that.
I am confused. Help please!
From the doc of AsyncTask
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the background computation
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Rather than an API reference, here's a little more description. First, many people will use an AsyncTask inline as an anonymous class; keep that in mind. It looks like you've extended it with your own class (which is totally fine), but it likely means you're passing the necessary data in the constructor and referencing it as class variables. In that case, some of the arguments won't make as much sense.
So picture an anonymous inline class of AsyncTask. The first thing it's going to do is run some processing in the background. To do that, you need a way to pass data to the doInBackground method (because you don't have a constructor to call and pass it data). So the first argument is the type of data you're going to pass to it. If you don't have to pass anything, use Void, or use Object, or anything at all, really, because it has to be part of the method signature but you'd ignore it anyway.
For many situations, one will want to provide progress updates. For example, you might use the Float type to represent percent complete, or Long to represent bytes read from a file, or String for general messages to a user. You use the progress type to pass out interim progress information (think of uploading a file to facebook or downloading a file, where it updates the notification status with the progress - this is where/how you'd do that). You've said you don't care about it in your case, so use Void and don't bother implementing any progress methods.
Finally, when the task completes, you need to get to the result in the onPostExecute. So your doInBackground will return a value (of this type) and the AsyncTask framework will pass it to onPostExecute. Again, this makes more sense for an anonymous class with no further body. If you'd hold any results in a class member, that's fine also (but unnecessary). If you don't need to do anything on complete, or don't need to pass any data, use Void (and return null from doInBackground). I find it's useful at the least to return a Boolean for "completed successfully or failed," so you have that information (which might influence whether you post a success or failure notification, as notification of task complete is a common onPostExecute operation).
Hope some more explanation with examples helps.
Those are for when you want to pass something to it at time of execution or passing between runInBackground and onPostExecute. You can simply make all three Void in class declaration.
AsyncTask | Android Developers
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the background computation.
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Android get data from internet (android.os.NetworkOnMainThreadException)

Ok, I have read a lot of questions here on StackOverflow but i still can't understand so i'm opening a new question.
I made a class which function connects to internet and fetches json as string. It works fine in normal Java Application but i can't get it work in my android project.
I'm getting next error: android.os.NetworkOnMainThreadException
So to my understanding I have to use AsyncTask but I don't know how to wrap my function into it.
Function looks like this:
public static String get(String url){
//connect and get data to string
// return string
}
Like I said it works fine in normal JavaApplication but not in android project.
Thx for help!
http://developer.android.com/reference/android/os/AsyncTask.html
Look at the sample
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
}
Your "get" function must be splitted into 2 separate function in this class
what you want to get in, put in
doInBackground
And what you want to do with data which you receive into
onPostExecute
As I understand you use AndroidHttpClient -> so you can not even try to perform your network operations in the UI thread - > so create separate thread for this purpose. You can either use AsynchTask, Thread + Handler or HandlerThread for this purpose, or you can try to experiment here with java.util.concurrent package.
NetworkOnMainThreadException | Android Developers
developer.android.com/... -
Class Overview. The exception that is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for ...
You can create the thread method which extends AsyncTask (as you correctly understood), and execute it with .execute().
Exactly how you set it up is up to you. Here's a link with a tutorial on spinning these threads:
http://www.vogella.com/articles/AndroidPerformance/article.html#concurrency_threads

How to make requests to server from Android applications

I'm currently developing an application on Android platform that needs to contact the main server multiple times to do various stuff. I'm now coping with the issue of software design in terms of making every request to the server in a separate thread (otherwise, I get a NetworkOnMainThreadException and it's not recommended to do so).
So I have 3 classes in my example:
The requester class that wants to, say, fill up a Spinner with data from a database located in a server.
The middle class that asks a DBConnection to perform a new connection, then wait for it to finish and parse the data to the appropriate format.
The lower class that makes the connection to the database and retrieves a raw String, which then is passed to the middle class to be parsed.
I know that for every connection made to the server, I'll have to create a new thread, so that's made in the class that establishes the connection (lower class) and waits for results. This way I don't overload the top layers of my software with AsyncTasks and stuff that they shouldn't be aware of.
The problem is that after I receive the data I have to parse it, and the do stuff with it. Also I have to fill up the spinner (as in the example).
I know it might be a good idea to make a DataFromServerListener interface or something like that, but I think it's gonna get cluttered with methods all around to handle data from server. On the other hand, I'd have to make every top class start the separate thread with an AsyncTask and might not be the best solution.
I'd really appreciate any suggestions on this subject. :D
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return "Executed";
}
#Override
protected void onPostExecute(String result) {
}
}
This is kind of what I needed. Actually, it solves problems I didn't take care of before.
http://www.codeproject.com/Articles/162201/Painless-AsyncTask-and-ProgressDialog-Usage

Categories

Resources