Upgrade to Pro — share decks privately, control downloads, hide ads and more …

droidkaigi-2017-renovation

 droidkaigi-2017-renovation

funnelbit

March 09, 2017
Tweet

More Decks by funnelbit

Other Decks in Technology

Transcript

  1. 3FQPTJUPSZ QBDLBHFߏ੒ w CPPLNBSLEPNBJO w &OUSZ w &OUSZKBWB .PEFM 

    w &OUSZ3FQPTJUPSZKBWB *OUFSGBDF  w &OUSZ3FQPTJUPSZ*NQMKBWB w &OUSZ.PEVMFKBWB
  2. 3FQPTJUPSZ *NQM public class EntryRepositoryImpl implements EntryRepository {
 BookmarkAPI mBookmarkAPI;


    @Inject
 public EntryRepositoryImpl(BookmarkAPI bookmarkAPI) {
 mBookmarkAPI = bookmarkAPI;
 } @Override
 public Single<List<Entry>> getGalleryEntries(Category category) {
 return mBookmarkAPI
 .getEntryListGallery(category.getId())
 .map(entries -> Lists.transform(entries, e -> new Entry(e, true)));
 }
 }
  3. 3FQPTJUPSZ .PEVMF @Module
 public abstract class EntryModule {
 @Singleton
 @Binds


    public abstract EntryRepository provideEntryRepository(EntryRepositoryImpl impl);
 }
  4. *OUFSBDUPS w ಺෦ʹ3FQPTJUPSZΛ࣋ͭ w ඞͣ3YͰฦ͢ w มߋՄೳͳঢ়ଶΛ࣋ͨͳ͍ w εϨουΛܾఆ͢Δ w

    ࠷ޙʹ͸ඞͣϝΠϯεϨουʹ໭͢ w *OUFSBDUPSΛ૊Έ߹Θͤͳ͍લఏͷઃܭ
  5. *OUFSBDUPS 
 public class GetUserPage {
 private final UserRepository mUserRepository;


    private final SchedulerSwitch mSchedulerSwitch;
 
 @Inject
 public GetUserPage(UserRepository repository, SchedulerSwitch schedulerSwitch) {
 mUserRepository = repository;
 mSchedulerSwitch = schedulerSwitch;
 }
 
 public Single<UserPage> execute(HatenaId hatenaId, int limit) {
 return mUserRepository
 .getUserPage(hatenaId, limit)
 .compose(mSchedulerSwitch.fromIOtoUI());
 }
 }
  6. *OUFSBDUPS 
 public class GetUserPage {
 private final UserRepository mUserRepository;


    private final SchedulerSwitch mSchedulerSwitch;
 
 @Inject
 public GetUserPage(UserRepository repository, SchedulerSwitch schedulerSwitch) {
 mUserRepository = repository;
 mSchedulerSwitch = schedulerSwitch;
 }
 
 public Single<UserPage> execute(HatenaId hatenaId, int limit) {
 return mUserRepository
 .getUserPage(hatenaId, limit)
 .compose(mSchedulerSwitch.fromIOtoUI());
 }
 }
  7. *OUFSBDUPS 
 public class GetUserPage {
 private final UserRepository mUserRepository;


    private final SchedulerSwitch mSchedulerSwitch;
 
 @Inject
 public GetUserPage(UserRepository repository, SchedulerSwitch schedulerSwitch) {
 mUserRepository = repository;
 mSchedulerSwitch = schedulerSwitch;
 }
 
 public Single<UserPage> execute(HatenaId hatenaId, int limit) {
 return mUserRepository
 .getUserPage(hatenaId, limit)
 .compose(mSchedulerSwitch.fromIOtoUI());
 }
 }
  8. *OUFSBDUPS 4DIFEVMFS4XJUDI w *05ISFBE.BJO5ISFBE public class SchedulerSwitch {
 private final

    Scheduler mIOScheduler;
 private final Scheduler mUIScheduler;
 
 @Inject
 public SchedulerSwitch(@IOScheduler Scheduler ioScheduler, @UIScheduler Scheduler uiScheduler) {
 mIOScheduler = ioScheduler;
 mUIScheduler = uiScheduler;
 }
 
 public <T> SchedulerSwitchTransformer<T> fromIOtoUI() {
 return new SchedulerSwitchTransformer<>(mIOScheduler, mUIScheduler);
 }
 }
  9. *OUFSBDUPS 4DIFEVMFS4XJUDI5SBOTGPSNFS public class SchedulerSwitchTransformer<T> implements
 ObservableTransformer<T, T>,
 FlowableTransformer<T, T>,


    SingleTransformer<T, T>,
 MaybeTransformer<T, T>,
 CompletableTransformer
 { …
 public SchedulerSwitchTransformer(Scheduler from, Scheduler to) {
 mFromScheduler = from;
 mToScheduler = to;
 }
 
 @Override
 public ObservableSource<T> apply(Observable<T> upstream) {
 return upstream.subscribeOn(mFromScheduler).observeOn(mToScheduler);
 } …
  10. $PNNFOUT7JFX.PEFM public class CommentsViewModel { … private final BehaviorSubject<Page<BookmarkCommentViewModel>> mPages

    = BehaviorSubject.create();
 public final Observable<Page<BookmarkCommentViewModel>> pages = mPages.hide();
 
 private final PublishSubject<Throwable> mErrors = PublishSubject.create();
 public final Observable<Throwable> errors = mErrors.hide(); 
 @Inject
 public CommentsViewModel(Observable<FragmentEvent> lifecycle,
 GetEntryCommentList getEntryCommentList,
 AddStar addStar,
 Target target) {
 mLifecycle = lifecycle;
 mGetEntryCommentList = getEntryCommentList;
 mAddStar = addStar; …
  11. $PNNFOU7JFX.PEFM public final class CommentViewModel {
 public final String profileImageUrl;


    public final String username;
 public final String comment;
 public final List<String> tags;
 public final String timestamp; 
 public ObservableList<HatenaStar> stars;
 private final AddStar mAddStar;
 
 private final PublishSubject<Throwable> mErrors;
 
 public CommentViewModel(
 String entryId,
 BookmarkComment bookmarkComment,
 AddStar addStar,
 PublishSubject<Throwable> errorsSubject)
 {
 …
 }
  12. $PNNFOU7JFX.PEFM 
 public void addStar() {
 // ελʔ௥Ճதͷදࣔɻ
 HatenaStar requesting

    = new HatenaStar(HatenaStar.Color.REQUESTING, null, null, true);
 stars.add(requesting);
 
 mAddStar.execute(mEntryStarInfo)
 .subscribe(
 () -> {
 stars.set(stars.size() - 1, new HatenaStar(HatenaStar.Color.YELLOW, null, null, true));
 },
 e -> {
 mErrors.onNext(new AddStarFailed());
 stars.remove(requesting);
 }
 );
 }
  13. 7JFX.PEFM /BWJHBUPS public interface LoginNavigator {
 void openLogin();
 
 @dagger.Module


    class Module {
 private final LoginNavigator mNavigator;
 
 public Module(LoginNavigator navigator) {
 mNavigator = navigator;
 }
 
 @Provides
 public LoginNavigator provideNavigator() {
 return mNavigator;
 }
 }
 }
  14. 7JFX.PEFM /BWJHBUPS public class TopicFragment extends BaseFragment { private final

    LoginNavigator mNavigator = () -> startActivity( new Intent(getActivity(), LoginActivity.class) ); …
  15. 7JFX.PEFM /BWJHBUPS @Nullable
 @Override
 public View onCreateView(...) {
 ((App) getActivity().getApplication())

    …
 .topicFragmentComponent()
 .loginNavigatorModule( new LoginNavigator.Module(mNavigator) )
 .build()
 .inject(this);
  16. 7JFX.PEFM /BWJHBUPS public class TopicViewModel { …
 private final LoginNavigator

    mNavigator;
 public final ObservableField<View.OnClickListener> onClickListener = new ObservableField<>(
 new View.OnClickListener(){
 @Override
 public void onClick(View view) {
 mNavigator.openLogin();
 }
 });