Friday minutes
MVP
RxJava
Javier de Pedro
Xes García
MVP
Xes García
Best practices - MVP
MVP vs MVC
Who is who?
Activity
Fragment
Custom Android View
New layer
Example
Requirements
- Close advertise after 3 secs
- Close advertise when button
pressed
- Go to activity when pressed
inside
- Load ad from CMS
Model
public class Interstitial implements Parcelable {
private String mTitle;
private String mImage;
private String mHref;
}
View - Class
public class InterstitialActivity extends BaseActivity implements InterstitialViewTranslator {
private NetworkImageView mInterstitialImage;
private View mLoader;
private InterstitialPresenter mPresenter;
}
View - OnCreate
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intersitital);
mInterstitialImage = (NetworkImageView)
findViewById(R.id.interstitial_image);
mLoader = findViewById(R.id.loader);
View closeButton = findViewById(R.id.interstitial_close);
closeButton.setOnClickListener(this);
mPresenter = new InterstitialPresenter(this, this);
}
View - OnClick
@Override
public void onClick (View v) {
switch (v.getId()){
case R.id.interstitial_close:
mPresenter.close();
break;
case R.id.interstitial_image:
mPresenter.goToInterstitial();
break;
}
}
View Translator interface
public interface InterstitialViewTranslator {
void startLoading();
void stopLoading();
void openNextActivity()
void showInterstitial(Interstitial interstitial);
}
View - Implementation
@Override
public void startLoading () {
mLoader.setVisibility(View.VISIBLE);
}
@Override
public void stopLoading () {
mLoader.setVisibility(View.GONE);
}
@Override
public void openNextActivity () {
Intent intent = new Intent(this, AnotherActivity.class);
}
@Override
public void showInterstitial (Interstitial interstitial) {
if(interstitial != null) {
mInterstitialImage.setImageUrl(interstitial.getImage(), VolleyUtil.getImageLoader());
mInterstitialImage.setOnClickListener(this);
}
}
Presenter - Class
public class InterstitialPresenter extends BasePresenter {
private InterstitialViewTranslator mViewTranslator;
private CloseRunnable mCloseRunnable;
private Handler mHandler;
}
Presenter - Constructor
public InterstitialPresenter(InterstitialViewTranslator viewTranslator){
mViewTranslator = viewTranslator;
if(mViewTranslator == null){
throw new NullPointerException(
"The presenter must have a view translator instance."
);
}
mHandler = new Handler();
restoreState(); // Loads a state if present to keep the time
loadInterstitial();
}
Presenter - Actions
private void loadInterstitial (){
mViewTranslator.startLoading();
InterstitialWebService.fetchInterstitial(new IBackgroundTaskCallback<Interstitial>() {
@Override
public void onCompleted (CustomException e, Interstitial interstitial) {
TotoLog.d("Interstitial loaded");
mViewTranslator.stopLoading();
if (interstitial != null) {
onLoadInterstitial(interstitial);
} else {
close();
}
}
});
}
private void onLoadInterstitial(Interstitial interstitial){
mViewTranslator.showInterstitial(interstitial);
startTimer();
}
View - Show ad
@Override
public void showInterstitial (Interstitial interstitial) {
if(interstitial != null) {
mInterstitialImage.setImageUrl(interstitial.getImage(),
VolleyUtil.getImageLoader());
mInterstitialImage.setOnClickListener(this);
}
}
Presenter - Last steps
public void pause () {
cancelTimerCallback();
saveState();
}
public void destroy(){
cancelTimerCallback();
}
Testing
Testing
environment
(mocks)
Presenter
Testing environment
(mocks)
Activity/View/Fragment
(lifecycle)
(view methods)
Services
Web Service
RxJava
Javier de Pedro
RxJava -
In Android… YES
(Started on April 2013)
(Android Weekly)
RxJava - What?
BORN
Deprecating the observer pattern
Microsoft first library
GOOD FOR
- Data management
- Stream read
- Event handling
- Thread sync
- Standard across languages
NOT SO GOOD FOR:
- Sync programming
- Noobies
RxJava - Philosophy
Everything is a Stream of data
RxJava - Observable
Special Observer pattern
ObservableClient
data retrieval
posibility
condition
Call to network
Go to database
Use a list
Read file
Awful name
Asynchronous iterator
subscribe
observe
RxJava - Ex. Observable
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> observer) {
try {
if (!observer.isUnsubscribed()) {
for (int i = 1; i < 5; i++) {
observer.onNext(i);
}
observer.onCompleted();
}
} catch (Exception e) {
observer.onError(e);
}
}
RxJava - Operations
Create
FlatMap
Filter
Buffer
ToSortedList
GroopBy
...
RxJava - Ex. Subscription
cityWebService.getCapitals()
.flatMap(cityList -> Observable.from(cityList))
.filter(city -> city.getPopulation() > 500,000)
.flatMap(city -> weatherService.getCurrentWeather(city)) // Runs requests in paralell
.toSortedList((cw1,cw2) -> cw1.getCityName().compare(cw2.getCityName()));
Gists
Presenter minimal example
https://gist.github.com/butelo/76b360003c13955072fd
RxJava minimal example
...

Mobgen - Android session MVP & Rx

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
    Example Requirements - Close advertiseafter 3 secs - Close advertise when button pressed - Go to activity when pressed inside - Load ad from CMS
  • 7.
    Model public class Interstitialimplements Parcelable { private String mTitle; private String mImage; private String mHref; }
  • 8.
    View - Class publicclass InterstitialActivity extends BaseActivity implements InterstitialViewTranslator { private NetworkImageView mInterstitialImage; private View mLoader; private InterstitialPresenter mPresenter; }
  • 9.
    View - OnCreate @Override publicvoid onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_intersitital); mInterstitialImage = (NetworkImageView) findViewById(R.id.interstitial_image); mLoader = findViewById(R.id.loader); View closeButton = findViewById(R.id.interstitial_close); closeButton.setOnClickListener(this); mPresenter = new InterstitialPresenter(this, this); }
  • 10.
    View - OnClick @Override publicvoid onClick (View v) { switch (v.getId()){ case R.id.interstitial_close: mPresenter.close(); break; case R.id.interstitial_image: mPresenter.goToInterstitial(); break; } }
  • 11.
    View Translator interface publicinterface InterstitialViewTranslator { void startLoading(); void stopLoading(); void openNextActivity() void showInterstitial(Interstitial interstitial); }
  • 12.
    View - Implementation @Override publicvoid startLoading () { mLoader.setVisibility(View.VISIBLE); } @Override public void stopLoading () { mLoader.setVisibility(View.GONE); } @Override public void openNextActivity () { Intent intent = new Intent(this, AnotherActivity.class); } @Override public void showInterstitial (Interstitial interstitial) { if(interstitial != null) { mInterstitialImage.setImageUrl(interstitial.getImage(), VolleyUtil.getImageLoader()); mInterstitialImage.setOnClickListener(this); } }
  • 13.
    Presenter - Class publicclass InterstitialPresenter extends BasePresenter { private InterstitialViewTranslator mViewTranslator; private CloseRunnable mCloseRunnable; private Handler mHandler; }
  • 14.
    Presenter - Constructor publicInterstitialPresenter(InterstitialViewTranslator viewTranslator){ mViewTranslator = viewTranslator; if(mViewTranslator == null){ throw new NullPointerException( "The presenter must have a view translator instance." ); } mHandler = new Handler(); restoreState(); // Loads a state if present to keep the time loadInterstitial(); }
  • 15.
    Presenter - Actions privatevoid loadInterstitial (){ mViewTranslator.startLoading(); InterstitialWebService.fetchInterstitial(new IBackgroundTaskCallback<Interstitial>() { @Override public void onCompleted (CustomException e, Interstitial interstitial) { TotoLog.d("Interstitial loaded"); mViewTranslator.stopLoading(); if (interstitial != null) { onLoadInterstitial(interstitial); } else { close(); } } }); } private void onLoadInterstitial(Interstitial interstitial){ mViewTranslator.showInterstitial(interstitial); startTimer(); }
  • 16.
    View - Showad @Override public void showInterstitial (Interstitial interstitial) { if(interstitial != null) { mInterstitialImage.setImageUrl(interstitial.getImage(), VolleyUtil.getImageLoader()); mInterstitialImage.setOnClickListener(this); } }
  • 17.
    Presenter - Laststeps public void pause () { cancelTimerCallback(); saveState(); } public void destroy(){ cancelTimerCallback(); }
  • 18.
  • 19.
  • 20.
    RxJava - In Android…YES (Started on April 2013) (Android Weekly)
  • 21.
    RxJava - What? BORN Deprecatingthe observer pattern Microsoft first library GOOD FOR - Data management - Stream read - Event handling - Thread sync - Standard across languages NOT SO GOOD FOR: - Sync programming - Noobies
  • 22.
    RxJava - Philosophy Everythingis a Stream of data
  • 23.
    RxJava - Observable SpecialObserver pattern ObservableClient data retrieval posibility condition Call to network Go to database Use a list Read file Awful name Asynchronous iterator subscribe observe
  • 24.
    RxJava - Ex.Observable Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> observer) { try { if (!observer.isUnsubscribed()) { for (int i = 1; i < 5; i++) { observer.onNext(i); } observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } }
  • 25.
  • 26.
    RxJava - Ex.Subscription cityWebService.getCapitals() .flatMap(cityList -> Observable.from(cityList)) .filter(city -> city.getPopulation() > 500,000) .flatMap(city -> weatherService.getCurrentWeather(city)) // Runs requests in paralell .toSortedList((cw1,cw2) -> cw1.getCityName().compare(cw2.getCityName()));
  • 27.