Issue
I have a WCF webservice that returns SQL Server database data in JSON format, Now i'm using AsyncTask for get this data in Android by this code :
public class FetchInfo extends AsyncTask {
private String year = "94";
private String month = "1";
private String requested_column = "";
private String kodemelli = "";
public FetchInfo(String year, String month,String requested_column, String kodemelli) {
this.year = year;
this.month = month;
this.requested_column = requested_column;
this.kodemelli = kodemelli;
}
@Override
protected String doInBackground(Object[] params) {
try {
System.out.println("guru");
DefaultHttpClient httpClient=new DefaultHttpClient();
//Connect to the server
HttpGet httpGet=new HttpGet("http://SERVERIP:8005/Service1.svc/checkLogin1?year="+year+"&month="+month+"&requested_column="+requested_column+"&kode_melli="+kodemelli);
//Get the response
String result = "";
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream stream=httpEntity.getContent();
result = convertStreamToString(stream);
//Convert the stream to readable format
if (result.contains("\"error\"") || result.contains("\"server error\"")){
Main.result = "0";
MainFish.result = "0";
}else {
Main.result = result;
MainFish.result = result;
}
} catch (Exception e) {
Main.result = "error";
MainFish.result = "error";
}
return "";
}
public static String convertStreamToString(InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
By this ,when the requests is more than for example 10 request, the response time is very long. From this topic How to speed up fetching of data from server using JSON? I realized that I should to use Retrofit instead AsyncTask to make my program work.
Now my question is how can convert AsyncTask class to a Retrofit?
Solution
Ok so first you will not use an async task with retrofit. Retrofit takes care of the async part. First you need do define a rest adapter.
Here is a default rest adapter with your parameters in it.
public class ApiClient {
private static ApiInterface sApiInterface;
public static ApiInterface getApiClient(Context context) {
//build the rest adapter
if (sApiInterface == null) {
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://SERVERIP:8005")
.build();
sApiInterface = restAdapter.create(ApiInterface.class);
}
return sApiInterface;
}
public interface ApiInterface {
// /Service1.svc/checkLogin1?year="+year+"&month="+month+"&requested_column="+requested_column+"&kode_melli="+kodemelli
@GET("/Service1.svc/checkLogin1")
void getYourObject(
@Query("year") String year,
@Query("month") String month,
@Query("requested_column") String requested_column,
@Query("kode_melli") String kodemelli,
RetrofitCallback<YourObjectModel> callback);
}
After you have a rest adapter you need a model to put the data in. Use jsonschema2pojo to convert valid JSON to a POJO model. Here is an example of one of my json responses and its model.
{
"id": "37",
"title": "",
"short_name": "",
"short_description": "",
"full_description": "",
"url": "http:\/\/\/shows\/programname",
"Image": {
"url": "https:\/\/s3.amazonaws.com\/image\/original\/b2mWDPX.jpg",
"url_sm": "https:\/\/s3.amazonaws.com\/image\/small\/b2mWDPX.jpg",
},
"image": "b2mWDPX.jpg",
"hosts": [{
"id": "651",
"display_name": "",
"username": "",
"Image": {
"url": "https:\/\/s3.amazonaws.com\/image\/original\/selfie.jpg",
"url_sm": "https:\/\/s3.amazonaws.com\/image\/small\/selfie.jpg",
}
}],
"airtimes": [{
"start": "11:00:00",
"end": "13:30:00",
"weekday": "6"
}],
"categories": [{
"id": "84",
"title": "Bluegrass",
"short_name": "bluegrass"
}],
"meta": []
}
I get this model. And a few others to go with it.
public class Program {
@Expose
private doublea.models.Airtime Airtime;
@Expose
private String id;
@Expose
private String title;
@SerializedName("short_name")
@Expose
private String shortName;
@SerializedName("full_description")
@Expose
private String fullDescription;
@SerializedName("short_description")
@Expose
private String shortDescription;
@Expose
private doublea.models.Image Image;
@SerializedName("image")
@Expose
private String imageName;
@Expose
private List<Host> hosts = new ArrayList<Host>();
@Expose
private List<Category> categories = new ArrayList<Category>();
@Expose
private List<Airtime> airtimes = new ArrayList<Airtime>();
/** Getters and Setters */
public Program() {
}
Then make sure you take care of failure cases.
public class RetrofitCallback<S> implements Callback<S> {
private static final String TAG = RetrofitCallback.class.getSimpleName();
@Override
public void success(S s, Response response) {
}
@Override
public void failure(RetrofitError error) {
Log.e(TAG, "Failed to make http request for: " + error.getUrl());
Response errorResponse = error.getResponse();
if (errorResponse != null) {
Log.e(TAG, errorResponse.getReason());
if (errorResponse.getStatus() == 500) {
Log.e(TAG, "Handle Server Errors Here");
}
}
}
}
And finally making the api call.
private void executeProgramApiCall(String year, String month, String requested_column, String kodemelli) {
ApiClient.getApiClient(this).getProgram(year, month, requested_column, kodemelli, new RetrofitCallback<Program>() {
@Override
public void success(YourObjectModel program, Response response) {
super.success(YourObjectModel , response);
//TODO: Do something here with your ObjectMadel
}
});
}
I would highly recommend taking a look at the retrofit documentation in case you need anything special like headers or request interceptors.
Answered By - doubleA Answer Checked By - Robin (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.