$30 off During Our Annual Pro Sale. View Details »

droidkaigi2016

funnelbit
February 18, 2016

 droidkaigi2016

funnelbit

February 18, 2016
Tweet

More Decks by funnelbit

Other Decks in Technology

Transcript

  1. %BHHFSͱ3FBMNΛ
    ར༻ͨ͠Ϟμϯͳ։ൃ
    ๺ଜɹྋ

    View Slide

  2. ࣗݾ঺հ
    w ๺ଜɹྋ
    w ͸ͯͳJEGVOOFMCJU
    w 5XJUUFSJEFYQFSPQFSP

    View Slide

  3. View Slide

  4. ͸ͯͳϒοΫϚʔΫ

    View Slide

  5. ژ౎

    View Slide

  6. ࠓ೔࿩͢͜ͱ
    w ϑϨʔϜϫʔΫ͔ΒϩδοΫΛ੾Γ཭͢
    w ӬଓԽ
    w αʔόαΠυͱฒߦͨ͠։ൃ
    w ϓϩμΫτνΣοΫ

    View Slide

  7. ϑϨʔϜϫʔΫ͔Βϩ
    δοΫΛ੾Γ཭͢

    View Slide

  8. ϑϨʔϜϫʔΫ
    w "OESPJE4%,͕ఏڙ͢ΔɺΞϓϦ΍ը໘ͷϥΠ
    ϑαΠΫϧͱڧ݁͘ͼ͍ͭͨΫϥε

    View Slide

  9. ϩδοΫΛͲ͜ʹॻ͔͘
    w º"DUJWJUZ 'SBHNFOUʹ௚઀ॻ͘
    w ංେԽɺςετෆՄೳ
    w ˛$VTUPN7JFXʹ௚઀ॻ͘
    w 7JFXͷϩδοΫ͸͜͜ʹॻ͚͹ྑ͍
    w ͦΕҎ֎ͷ৔ॴ

    View Slide

  10. ͦΕҎ֎ͷ৔ॴʁ
    w ϩδοΫΛந৅Խͯ͠੾Γग़͢
    w d$POUSPMMFS d.BOBHFSͳͲɺϩδοΫ୲౰
    ΫϥεΛ࡞Δ

    View Slide

  11. ϩδοΫͷந৅ͷ*OTUBODFΛ
    Ͳ͜Ͱ࡞Δ͔ʁ
    w ˛ར༻͢Δ"DUJWJUZʹ௚઀ॻ͘
    w ݁ͼ͖͕ͭڧ͘ͳΔ
    w ςετͷ࣌ʹڍಈΛม͍͑ͨͱ͖͸ʁ
    w ˓ར༻͢Δͷ֎෦Ͱੜ੒ɾ؅ཧ
    w ґଘͤ͞ͳ͍
    w ςετ࣌ʹ͸੾Γସ͑Δɺͱ͍ͬͨ͜ͱ͕༰қ
    w %*

    View Slide

  12. ૉ๿ͳ%*
    public EntryManager(APIClient apiClient) {
    this.mAPIClient = apiClient;

    ...
    }

    View Slide

  13. ૉ๿ͳ%*࢖͑ͳ͍໰୊
    w "DUJWJUZͱ'SBHNFOUʹରͯ͠͸ແྗ
    w ίϯετϥΫλͰΠϯελϯε౉ͤͳ͍
    w 1BSDFMBCMFʹͯ͠ؤுΕ͹Ͱ͖ͳ͍͜ͱ͸ͳ͍͕
    ؤுΓͨ͘ͳ͍
    w ͜ͷ໰୊͸%*ίϯςφ͕͋Ε͹ղܾ͢Δ

    View Slide

  14. %*ίϯςφ
    w ґଘ஫ೖΛߦ͏ϑϨʔϜϫʔΫ
    w खಈͰ࢓૊ΈΛ༻ҙ͠ͳͯ͘ྑ͍
    w Πϯελϯε؅ཧ΋ߦͳ͑Δ

    View Slide

  15. Ͳͷ%*ίϯςφΛ࢖͏΂͖
    ͔ʁ
    w 3PCP(VJDF
    w %BHHFS
    w %BHHFS

    View Slide

  16. %BHHFS

    View Slide

  17. %BHHFS
    w IUUQTHJUIVCDPNHPPHMFEBHHFS
    w %*ίϯςφ
    w 4RVBSF͕։ൃͯͨ͠%BHHFSͷHPPHMFGPSL

    View Slide

  18. %BHHFSͷར఺
    w ίϯύΠϧ࣌ʹίʔυੜ੒͠ґଘղܾ
    w ࣮ߦதͷύϑΥʔϚϯεʹӨڹ͠ͳ͍
    w σόοάͰίʔυΛ௥͍΍͍͢

    View Slide

  19. %*ͷߏ੒
    w .PEVMF
    w *OTUBODFͷੜ੒ํ๏Λهड़
    w $PNQPOFOU
    w .PEVMF಺ͷ*OTUBODFΛͲ͜ʹJOKFDU͢Δ͔ه

    w ֊૚ߏ଄Λ΋ͨͤͯ໾ׂΛ෼୲͠໌֬Խ

    View Slide

  20. .PEVMF
    @Module 

    public class MainModule {
    ...
    @Provides

    EntryManager provideEntryManager() {
    return new EntryManager(mService);
    }
    ...

    View Slide

  21. $PNQPOFOU
    @Component(modules = MainModule.class)
    public interface MainComponent {
    void inject(MainActivity mainActivity)

    View Slide

  22. *OKFDU
    public class MainActivity extends AppCompatActivity {
    @Inject EntryManager mEntryManager;
    @Override 

    protected void onCreate(Bundle b) {
    ...
    ((App) getApplication())
    .component()
    .inject(this);
    ...

    View Slide

  23. 5FTU༻.PEVMF
    @Module 

    public class MainTestModule {
    ...
    @Provides

    EntryManager provideEntryManager() {
    return new EntryManager(mStubService);
    }
    ...

    View Slide

  24. ςετ༻$PNQPOFOU
    @Component(modules = MainTestModule.class)
    public interface MainTestComponent {
    void inject(EntryManagerTestCase testCase)

    View Slide

  25. *OKFDU ςετ

    public class EntryManagerTestCase extends
    InstrumentationTestCase {

    …

    @Inject

    EntryManager mEntryManager;


    public testGetEntries() {
    assertEquals(
    "ΤϯτϦऔಘͰ͖͍ͯΔ",
    false,
    mEntryManager.getEntries().isEmpty());
    }

    }

    View Slide

  26. $PNQPOFOUͷ෼͚ํ
    w "DUJWJUZ΍'SBHNFOUຖʹ෼͚Δʁ
    w ਺͕υϯυϯ૿͍͑ͯ͘
    w ໾ׂ͝ͱʹ෼͚Δ
    w ֊૚ߏ଄Λ࡞ͬͯࡉ෼Խ

    View Slide

  27. 4VC$PNQPOFOU
    @Component(modules = MainModule.class)

    public interface MainComponent {

    void inject(App app);


    // Activities

    void inject(RootActivity rootActivity);


    // Fragments

    void inject(MainSettingsFragment mainSettingsFragment);


    // Subcomponents

    UserComponent userComponent(UserModule userModule);
    }

    View Slide

  28. 4VC$PNQPOFOU
    @Subcomponent(modules = UserModule.class)

    public interface UserComponent {


    // Fragments

    void inject(MyFragment myFragment);


    UserController userController();

    }

    View Slide

  29. $PNQPOFOUΛऔಘ
    public class MyFragment extends Fragment {
    MainComponent mainComponent =
    App.get(getActivity())

    .getMainComponent();

    UserComponent userComponent =
    mainComponent.userComponent(
    new UserModule(
    mainComponent.getRealm(),
    args.getString(ARGS_USER_ID)));

    userComponent.inject(this);
    }

    View Slide

  30. ӬଓԽ

    View Slide

  31. ӬଓԽ͢Δ໨త
    w 8FC"1*͔ΒͷϨεϙϯεΛӬଓԽ
    w ΦϑϥΠϯ༻ͷΩϟογϡσʔλͷͨΊ
    w "DUJWJUZ΍'SBHNFOUͷ࠶ੜ੒࣌ʹ෮ؼ͢ΔͨΊ
    w ෳ਺ͷը໘Ͱಉ͡σʔλΛදࣔ͢Δͱ͖ͷҰ؏
    ੑΛอͪ΍͘͢͢ΔͨΊ

    View Slide

  32. ӬଓԽ͢Δखஈ
    w º4IBSFE1SFGFSFODFTʹೖΕΔ
    w ˛'JMFʹॻ͖ͩ͢
    w ˓42-JUFʹೖΕΔ
    w ˓3FBMNΛ࢖͏

    View Slide

  33. 42-JUF
    w "OESPJEඪ४ͳͷͰ҆৺ײ͕͋Δ
    w ࣗྗͰॻ͘ͷ͸গʑ໘౗͍͘͞
    w 03.࢖͏ʁ
    w ࢖͍΍͢͞ɺૣ͞ɺ҆ఆɺকདྷੑʜ

    View Slide

  34. 3FBMN
    w ։ൃ͕׆ൃ
    w 42-JUFͷΑ͏ͳ໘౗ͳ͜ͱΛ͠ͳͯ͘ྑ͍
    w ˛όʔδϣϯະຬ

    View Slide

  35. 3FBMNΛ࢖͏
    w J04ΞϓϦͱ ՄೳͳݶΓ
    ڞ௨ͷϞσϧΛ࣋ͪͨ
    ͍ͨΊ
    w ։ൃ׆ൃ͔ͩΒԿ͔͋ͬͯ΋ରॲ͞ΕΔͰ͋Ζ
    ͏

    View Slide

  36. 3FBMN

    View Slide

  37. 3FBMN
    w 42-JUFΛஔ͖׵͑͏Δ.PCJMFEBUBCBTF
    w 03.ͷػೳ΋࣋ͭ
    w ߴ଎
    w J04Ͱ΋ར༻Մೳ

    View Slide

  38. 3FBMNΛ࢖͏
    new RealmConfiguration.Builder(context)

    .name("realm")

    .schemaVersion(1L)

    .build();

    View Slide

  39. 3FBMNΛ࢖͏
    RealmResults followingEntries =
    mRealm.where(Entry.class)
    .equalTo("isFollowing",true)
    .findAllSortedAsync(
    "createdAt",
    Sort.DESCENDING);

    View Slide

  40. "DUJWJUZੜ੒࣌ʹҾ͘
    public class MainActivity extends AppCompatActivity {

    public void onCreate(Bundle savedInstanceState) {
    mRealmResults = mRealm.where().findAllAsync()

    }
    w ͙͢͞·3FBMN3FTVMUTΛಘΔ
    w ਖ਼͘͠෮ݩ͢ΔͨΊʹ΋࢖͏

    View Slide

  41. "EBQUFSʹ3FBMN3FTVMU
    public class EntriesAdapter {
    public EntriesAdapter(RealmResults entries) {

    mEntries = entries;

    mRealmChangeListener = new RealmChangeListener() {

    @Override

    public void onChange() {

    mListItems = getItems();

    EpisodesAdapter.this.notifyDataSetChanged();

    }

    };
    …

    }

    View Slide

  42. "EBQUFSʹ3FBMN3FTVMU
    public class EntriesAdapter {

    @Override

    public void onAttachedToRecyclerView(RecyclerView
    recyclerView) {

    super.onAttachedToRecyclerView(recyclerView);

    mResults.addChangeListener(mRealmChangeListener);

    }


    @Override

    public void onDetachedFromRecyclerView(RecyclerView
    recyclerView) {

    mResults.removeChangeListener(mRealmChangeListener);

    super.onDetachedFromRecyclerView(recyclerView);

    }

    View Slide

  43. "DUJWJUZؒͷσʔλड͚౉͠
    Intent intent = new Intent(context,
    EpisodeActivity.class);
    intent.putExtra(EXTRA_ID, Id);
    w 3FBMNͷ*%Λ౉͢͜ͱʹͯ͠͠·͏
    w ࠶ੜ੒ʹ΋උ͑ΕΔ͜ͱʹͳΔ

    View Slide

  44. 3FBMN
    Λ
    %BHHFS
    Ͱ
    εϨου͝ͱʹ*OKFDU

    View Slide

  45. εϨου·ͨ͛ͳ͍໰୊
    w 3FBMN*OTUBODF͕࡞੒͞ΕͨεϨου͔Βଞͷ
    εϨουͰ࢖͑ͳ͍
    w ͔͠͠*OKFDU͸PO$SFBUF
    Ͱߦ͍͍ͨ
    w ʮผεϨου͕ཉ͍࣌͠ʹ*OKFDU͢Δ࢓૊Έʯ͕
    ඞཁ

    View Slide

  46. %BHHFSͷ1SPWJEFSΛ࢖͏

    @Inject public EntryPrefetcher(Provider
    realmProvider) extends ThreadPoolExecutor {
    mRealmProvider = realmProvider;

    private static class Task implements Callable {
    @Override

    public String call() throws Exception {
    Realm realm = mRealmProvider.get();

    }

    View Slide

  47. αʔόαΠυ
    ͱ
    ฒߦͨ͠։ൃ

    View Slide

  48. αʔόαΠυͱฒߦͨ͠։ൃ
    w "1*͕ඞͣ͠΋ઌߦ͢Δͱ͸ݶΒͳ͍
    w μϛʔσʔλΛΞϓϦ಺෦ʹ͔࣋ͭʁ
    w "1*ʹมߋ͕͋ͬͨ࣌ʹ໘౗
    w J04ଆ΋ಉ࣌ʹมߋ͢Δඞཁ͕ग़ͯ͘Δ

    View Slide

  49. 4UVC4FSWFS

    View Slide

  50. 4UVC4FSWFS
    w μϛʔͷϨεϙϯεΛฦ͢αʔόΛ࡞Δ
    w "1*4DIFNB όϦσʔλͱͯ͠ར༻

    w IUUQTHJUIVCDPNIJUPEF"1*4DIFNB

    View Slide

  51. 4UVC4FSWFS
    SFTPVSDFMPHJO@SFRVFTU\
    UZQFPCKFDU
    EFTDSJQUJPOϩάΠϯϦΫΤετ
    QSPQFSUJFT\
    FNBJM@BEESFTT\
    UZQFTUSJOH
    EFTDSJQUJPOϝʔϧΞυϨε
    FYBNQMFBCD!FYBNQMFDPN
    ^
    QBTTXPSE\
    UZQFTUSJOH
    EFTDSJQUJPObύεϫʔυ
    FYBNQMF1BTTXSE
    ^
    ^
    SFRVJSFE<FNBJM@BEESFTT QBTTXPSE>
    ^

    View Slide

  52. ςετͰ΋4UVC4FSWFSΛ
    ࢖͏
    w ˛μϛʔͷ+40/Λ಺෦ʹ࣋ͬͯςετʹར༻
    w "1*มΘΔͨͼʹมߋͤͶ͹ͳΒͳ͍
    w "1*ͷมߋʹςετ͕ؾ෇͚ͳ͍
    w ̋"1*ͷαʔόΛ௚઀ୟ͘
    w μϛʔσʔλෆཁ
    w มߋʹςετ͕ؾ͕ͭ͘

    View Slide

  53. ϓϩμΫτνΣοΫ

    View Slide

  54. ϓϩμΫτνΣοΫ
    w ژ౎ɾ౦ژʹΦϑΟε͕͋Δ
    w ౦ژʹ΋σβΠφʔ͕͍Δ
    w ख৮Γ͸௚઀৮Εͳ͍ͱΘ͔Βͳ͍

    View Slide

  55. #FUB#Z$SBTIMZUJDT

    KFOLJOT

    GBTUMBOF

    View Slide

  56. #FUB
    w #FUB#Z$SBTIMZUJDTΛ࢖ͬͯ#FUB഑৴
    w ഑৴ͷλΠϛϯά͸KFOLJOTʹ೚ͤΔ

    View Slide

  57. KFOLJOT
    w ϒϥϯνΛݟͯͯɺNBTUFSʹϚʔδ͞ΕͨΒ
    #FUBΛඈ͹͢
    w εΫϦʔϯγϣοτΛࡱͬͯ؆қతͳσβΠϯ֬

    w "1*ຖͷࠩҟ౳Λ֬ೝ
    w 4MBDLʹ௨஌

    View Slide

  58. GBTUMBOF
    (JUIVC࿈ܞ
    EBUB\TUBUFTUBUF UBSHFU@VSMUBSHFU@VSM
    DPOUFYUDPOUFYU EFTDSJQUJPO^
    IFBEFST\"VUIPSJ[BUJPOUPLFO\UPLFO^^
    &YDPOQPTU VSM IFBEFSTIFBEFST CPEZ
    EBUBUP@KTPO

    View Slide

  59. GBTUMBOF
    4MBDL࿈ܞ
    TMBDL
    NFTTBHFSPDLFUϏϧυ͕׬ྃ͠·ͨ͠SPDLFU
    DIBOOFMBQQ
    TVDDFTTUSVF
    QBZMPBE\
    #VJME%BUF5JNFOFXUP@T
    ^
    EFGBVMU@QBZMPBET<HJU@CSBODI HJU@BVUIPS>


    View Slide

  60. ςετ࣮ߦ
    EFTD3VOTBMMUIFUFTUT
    MBOFUFTUEP
    HSBEMF UBTLD$

    FOE

    View Slide

  61. ·ͱΊ
    w ϑϨʔϜϫʔΫ͔ΒϩδοΫΛ੾Γ཭͢
    w ϩδοΫͷந৅Խɺ%BHHFSͰ*OKFDU
    w ӬଓԽ
    w 3FBMNΛར༻
    w αʔόαΠυͱฒߦͨ͠։ൃ
    w 4UVC4FSWFSΛར༻
    w ϓϩμΫτνΣοΫ
    w #FUB#Z$SBTIMZUJDT KFOLJOT GBTUMBOF

    View Slide

  62. ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide