This is what they say(Eventbus): Less code, better quality. And you don't need to implement a single interface!
Most of us have recently started using Retrofit for REST API calls. So you all must be familiar with it. I have been doing some RnD since last few days and ended up writing a sample code(yes its completely written by me :P there could be few issues but I made every attempt to make it easily understandable) which is a combo of Retrofit and Eventbus & few other libs.
For further details on Events or Retrofit please follow the links at the bottom of the blog.
Here I am taking an example of a simple user login functionality. First I create an Activity LoginActivity which registers Eventbus inside onCreate method and unregisters it inside OnDestroy method of the Activity lifecycle.
/**
* Defines the user interface for user login.
*
* @author kthakur
*
* @version 0.1
*
*/
public class LoginActivity extends ActionBarActivity implements ProgressListener{
EventBus bus = EventBus.getDefault();
@InjectView(R.id.button1) Button start_button;
@InjectView(R.id.textView1)TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
//register EventBus
bus.register(this);
}
@OnClick(R.id.button1)
public void start() {
// just an example
new LoginApi(LoginActivity.this,LoginActivity.this);
}
@Override
public void showProgress() {
ProgressUtility.showProgress(LoginActivity.this, "Please wait..");
}
/**
* Called when the bus posts an event for no Internet connection.
* @param event
*/
public void onEvent(NoInternetEvent event) {
dismissProgress();
}
/**
* Called when the bus posts an event for successful result.
*
* <br>Call onEvent: Called in the same thread (default)
* <br>Call onEventMainThread: Called in Android UI's main thread
* <br>Call onEventBackgroundThread: Called in the background thread
* <br>Call onEventAsync: Called in a separate thread
*
* @param event
*/
public void onEvent(ApiResultEvent event) {
dismissProgress();
LoginResponse response = (LoginResponse) event.getResponse();
textView.setText("User Id: "+response.getUserLoginResult().getUserDetail()[0].getUserID());
}
/**
* Called when the bus posts an event for service failure.
* @param event
*/
public void onEvent(ApiErrorEvent event) {
dismissProgress();
Log.d("ApiErrorEvent", ""+event.getError());
}
/**
* Called when the bus posts an event for exception while GSON parsing.
* @param event
*/
public void onEvent(ExceptionEvent event) {
dismissProgress();
}
/**
* Dismiss progress dialog
*/
public void dismissProgress(){
if(ProgressUtility.isShowingProgress()){
ProgressUtility.dismissProgress();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//unregister EventBus
bus.unregister(this);
}
}
Here we send a request to the server, fetch response, performs Gson parsing and returns the result to our Activity as an event in the bus: I have posted 4 different events (NoInternetEvent, ApiResultEvent, ApiErrorEvent, ExceptionEvent) here which I have customized in a way that can be used throughout the App for all the Rest API calls. They are defined later below:
/**
* This class is used to authenticate user via web service and read
* the results returned in a web service and communicate it back to the Activity.
*/
public class LoginApi implements UrlListener{
Activity activity;
LoginRestApi loginRestApi;
ProgressListener progressListener;
EventBus bus = EventBus.getDefault();
/**
* Parameterized constructor.
*
* @param activity: Context of the Activity from which it is called.
* @param progressListener: Progress listener
* @param loginData: Login data object
*/
public LoginApi(Activity activity,ProgressListener progressListener) {
this.activity = activity;
this.progressListener = progressListener;
loginRequest();
}
/**
* Create login request.
*
* @param loginData
* @param resultListner
* @param retrofitListner
*/
public void loginRequest() {
//check for Internet
if(!Utilities.checkInternet(activity)){
//posts no Internet status back to the Activity
NoInternetEvent event = new NoInternetEvent(false);
bus.post(event);
return;
}
//start the progress bar
progressListener.showProgress();
LoginData loginData = new LoginData();
loginData.setEmailID("abc@xyz.com");
loginData.setPassword("aaaaaa");
getApi().login(loginData, new Callback<Response>() {
@Override
public void failure(RetrofitError error) {
ApiErrorEvent event=new ApiErrorEvent(error);
// Post the event
bus.post(event);
}
@Override
public void success(Response response, Response arg1) {
handleResponse(response);
}
});
}
/**
* Handle login response, performs GSON parsing.
* @param response
*/
protected void handleResponse(Response response) {
String jsonString = Utilities.parseTypedInput(response.getBody());
if (jsonString == null)
return;
try {
Gson gson = new Gson();
LoginResponse loginResponse = gson.fromJson(jsonString, LoginResponse.class);
ApiResultEvent event = new ApiResultEvent(loginResponse);
String UserID = loginResponse.getUserLoginResult().getUserDetail()[0].getUserID();
// Post the event back to the Activity with login response.
bus.post(event);
}
catch (Exception e) {
ExceptionEvent event = new ExceptionEvent(e);
// Post the event back to the activity with exception.
bus.post(event);
}
}
/**
* Create rest adapter.
* HOST_ADDRESS_URL is the web service endpoint
*/
private LoginRestApi getApi() {
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter restAdapter = new RestAdapter.Builder().
setClient(new OkClient(okHttpClient)).setEndpoint(HOST_ADDRESS_URL)
.setLogLevel(LogLevel.BASIC).build();
return restAdapter.create(LoginRestApi.class);
}
}
<<---------------- Utilities method parseTyedInput used above------------------->>
/**
* Parse Retrofit TypedInput
*
* @return parsed string or null
*/
public static String parseTypedInput(TypedInput body) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
if (body == null)
return null;
try {
reader = new BufferedReader(new InputStreamReader(body.in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}catch (IOException e) { e.printStackTrace();}
}
catch (IOException e) { e.printStackTrace(); }
return sb.toString();
}
/**
* API calls.
* Use your respective url, method name and params.
*/
public class UrlGenerator {
interface LoginRestApi {
@POST("/Login.svc/UserLogin")
void login(@Body Object param_object, Callback<retrofit.client.Response> cb);
}
interface GetCityRestApi {
@GET("/Common.svc/GetCity")
void getCity(Callback<Response> cb);
}
}
Now define different events that are important for us while making a Rest API call. You can define any no and kind of events as per your convenience. I have used 4 types of events: first for no internet connectivity, second for any error during API call, third for successfull result and fourth one for any exception during the complete process.
/**
* Reports Internet connectivity status.
*/
public class NoInternetEvent {
boolean value;
public NoInternetEvent(boolean value) {
this.value = value;
}
public boolean getException() {
return value;
}
}
/**
* Reports error during API call.
*/
public class ApiErrorEvent {
RetrofitError error;
public ApiErrorEvent(RetrofitError error){
this.error = error;
}
public RetrofitError getError(){
return error;
}
}
/**
* Reports result returned in the API call.
*/
public class ApiResultEvent {
Object _class;
public ApiResultEvent(Object _class) {
this._class = _class;
}
public Object getResponse() {
return _class;
}
}
/**
* Reports error during API call.
*/
public class ExceptionEvent {
Exception exception;
public ExceptionEvent(Exception exception){
this.exception = exception;
}
public Exception getException(){
return exception;
}
}
I have put most of the code here, a little effort would be required to put all these classes together and make necessary declarations to have an executable code.
Library dependencies:
1. Retrofit 1.9.0
2. Event Bus 2.4.0
3. Butterknife 6.1.0 (for UI annotations)
4. Lombok (for getter setter)
5. Gson2.2.4
6. Okhttp 2.2.0 (url connection)
7. Okio 1.0.1
Referneces:
http://greenrobot.github.io/EventBus/
https://github.com/greenrobot/EventBus/blob/master/HOWTO.md
http://square.github.io/retrofit/
Download source code from GithHub:
https://github.com/kamalthakur2305/RetroEventBus
Let me know if anyone needs any assistance in understanding and executing. I'd highly appreciate your thoughts, criticisms, or suggestions.
Most of us have recently started using Retrofit for REST API calls. So you all must be familiar with it. I have been doing some RnD since last few days and ended up writing a sample code(yes its completely written by me :P there could be few issues but I made every attempt to make it easily understandable) which is a combo of Retrofit and Eventbus & few other libs.
For further details on Events or Retrofit please follow the links at the bottom of the blog.
Here I am taking an example of a simple user login functionality. First I create an Activity LoginActivity which registers Eventbus inside onCreate method and unregisters it inside OnDestroy method of the Activity lifecycle.
/**
* Defines the user interface for user login.
*
* @author kthakur
*
* @version 0.1
*
*/
public class LoginActivity extends ActionBarActivity implements ProgressListener{
EventBus bus = EventBus.getDefault();
@InjectView(R.id.button1) Button start_button;
@InjectView(R.id.textView1)TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
//register EventBus
bus.register(this);
}
@OnClick(R.id.button1)
public void start() {
// just an example
new LoginApi(LoginActivity.this,LoginActivity.this);
}
@Override
public void showProgress() {
ProgressUtility.showProgress(LoginActivity.this, "Please wait..");
}
/**
* Called when the bus posts an event for no Internet connection.
* @param event
*/
public void onEvent(NoInternetEvent event) {
dismissProgress();
}
/**
* Called when the bus posts an event for successful result.
*
* <br>Call onEvent: Called in the same thread (default)
* <br>Call onEventMainThread: Called in Android UI's main thread
* <br>Call onEventBackgroundThread: Called in the background thread
* <br>Call onEventAsync: Called in a separate thread
*
* @param event
*/
public void onEvent(ApiResultEvent event) {
dismissProgress();
LoginResponse response = (LoginResponse) event.getResponse();
textView.setText("User Id: "+response.getUserLoginResult().getUserDetail()[0].getUserID());
}
/**
* Called when the bus posts an event for service failure.
* @param event
*/
public void onEvent(ApiErrorEvent event) {
dismissProgress();
Log.d("ApiErrorEvent", ""+event.getError());
}
/**
* Called when the bus posts an event for exception while GSON parsing.
* @param event
*/
public void onEvent(ExceptionEvent event) {
dismissProgress();
}
/**
* Dismiss progress dialog
*/
public void dismissProgress(){
if(ProgressUtility.isShowingProgress()){
ProgressUtility.dismissProgress();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//unregister EventBus
bus.unregister(this);
}
}
Here we send a request to the server, fetch response, performs Gson parsing and returns the result to our Activity as an event in the bus: I have posted 4 different events (NoInternetEvent, ApiResultEvent, ApiErrorEvent, ExceptionEvent) here which I have customized in a way that can be used throughout the App for all the Rest API calls. They are defined later below:
/**
* This class is used to authenticate user via web service and read
* the results returned in a web service and communicate it back to the Activity.
*/
public class LoginApi implements UrlListener{
Activity activity;
LoginRestApi loginRestApi;
ProgressListener progressListener;
EventBus bus = EventBus.getDefault();
/**
* Parameterized constructor.
*
* @param activity: Context of the Activity from which it is called.
* @param progressListener: Progress listener
* @param loginData: Login data object
*/
public LoginApi(Activity activity,ProgressListener progressListener) {
this.activity = activity;
this.progressListener = progressListener;
loginRequest();
}
/**
* Create login request.
*
* @param loginData
* @param resultListner
* @param retrofitListner
*/
public void loginRequest() {
//check for Internet
if(!Utilities.checkInternet(activity)){
//posts no Internet status back to the Activity
NoInternetEvent event = new NoInternetEvent(false);
bus.post(event);
return;
}
//start the progress bar
progressListener.showProgress();
LoginData loginData = new LoginData();
loginData.setEmailID("abc@xyz.com");
loginData.setPassword("aaaaaa");
getApi().login(loginData, new Callback<Response>() {
@Override
public void failure(RetrofitError error) {
ApiErrorEvent event=new ApiErrorEvent(error);
// Post the event
bus.post(event);
}
@Override
public void success(Response response, Response arg1) {
handleResponse(response);
}
});
}
/**
* Handle login response, performs GSON parsing.
* @param response
*/
protected void handleResponse(Response response) {
String jsonString = Utilities.parseTypedInput(response.getBody());
if (jsonString == null)
return;
try {
Gson gson = new Gson();
LoginResponse loginResponse = gson.fromJson(jsonString, LoginResponse.class);
ApiResultEvent event = new ApiResultEvent(loginResponse);
String UserID = loginResponse.getUserLoginResult().getUserDetail()[0].getUserID();
// Post the event back to the Activity with login response.
bus.post(event);
}
catch (Exception e) {
ExceptionEvent event = new ExceptionEvent(e);
// Post the event back to the activity with exception.
bus.post(event);
}
}
/**
* Create rest adapter.
* HOST_ADDRESS_URL is the web service endpoint
*/
private LoginRestApi getApi() {
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter restAdapter = new RestAdapter.Builder().
setClient(new OkClient(okHttpClient)).setEndpoint(HOST_ADDRESS_URL)
.setLogLevel(LogLevel.BASIC).build();
return restAdapter.create(LoginRestApi.class);
}
}
<<---------------- Utilities method parseTyedInput used above------------------->>
/**
* Parse Retrofit TypedInput
*
* @return parsed string or null
*/
public static String parseTypedInput(TypedInput body) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
if (body == null)
return null;
try {
reader = new BufferedReader(new InputStreamReader(body.in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}catch (IOException e) { e.printStackTrace();}
}
catch (IOException e) { e.printStackTrace(); }
return sb.toString();
}
/**
* API calls.
* Use your respective url, method name and params.
*/
public class UrlGenerator {
interface LoginRestApi {
@POST("/Login.svc/UserLogin")
void login(@Body Object param_object, Callback<retrofit.client.Response> cb);
}
interface GetCityRestApi {
@GET("/Common.svc/GetCity")
void getCity(Callback<Response> cb);
}
}
Now define different events that are important for us while making a Rest API call. You can define any no and kind of events as per your convenience. I have used 4 types of events: first for no internet connectivity, second for any error during API call, third for successfull result and fourth one for any exception during the complete process.
/**
* Reports Internet connectivity status.
*/
public class NoInternetEvent {
boolean value;
public NoInternetEvent(boolean value) {
this.value = value;
}
public boolean getException() {
return value;
}
}
/**
* Reports error during API call.
*/
public class ApiErrorEvent {
RetrofitError error;
public ApiErrorEvent(RetrofitError error){
this.error = error;
}
public RetrofitError getError(){
return error;
}
}
/**
* Reports result returned in the API call.
*/
public class ApiResultEvent {
Object _class;
public ApiResultEvent(Object _class) {
this._class = _class;
}
public Object getResponse() {
return _class;
}
}
/**
* Reports error during API call.
*/
public class ExceptionEvent {
Exception exception;
public ExceptionEvent(Exception exception){
this.exception = exception;
}
public Exception getException(){
return exception;
}
}
I have put most of the code here, a little effort would be required to put all these classes together and make necessary declarations to have an executable code.
Library dependencies:
1. Retrofit 1.9.0
2. Event Bus 2.4.0
3. Butterknife 6.1.0 (for UI annotations)
4. Lombok (for getter setter)
5. Gson2.2.4
6. Okhttp 2.2.0 (url connection)
7. Okio 1.0.1
Referneces:
http://greenrobot.github.io/EventBus/
https://github.com/greenrobot/EventBus/blob/master/HOWTO.md
http://square.github.io/retrofit/
Download source code from GithHub:
https://github.com/kamalthakur2305/RetroEventBus
Let me know if anyone needs any assistance in understanding and executing. I'd highly appreciate your thoughts, criticisms, or suggestions.
Slot Machines in Slot Machines in New York City - JTHub
ReplyDeleteSlot Machines in 울산광역 출장샵 Slot 진주 출장샵 Machines 나주 출장마사지 in 거제 출장샵 New York City · Casinos Near The Canal. · Slots for sale near Canal Park · Slots for sale near The 여수 출장마사지 Canal · Casino in Queens