Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
droidkaigi2016
Search
funnelbit
February 18, 2016
Technology
8.5k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
droidkaigi2016
funnelbit
February 18, 2016
More Decks by funnelbit
See All by funnelbit
Hatena Engineer Seminar #9
funnelbit
5
7.5k
droidkaigi-2017-renovation
funnelbit
10
11k
Dart
funnelbit
0
310
BottomBarAndSnackBar
funnelbit
0
560
Dagger2 Optional bindings
funnelbit
0
620
WearableRecyclerView
funnelbit
1
860
QucikSettingsTileAPI
funnelbit
0
390
Mobile Vision
funnelbit
0
500
AwarenessAPI
funnelbit
0
170
Other Decks in Technology
See All in Technology
デザインレビューは自動化できるのか?─ Flutter × Figma で UI 品質保証を考える
techiro
2
720
詳解 never 型 - ボトム型の性質を深掘り
nealle
0
130
書き手が人でもAIでも正しくなる道、SREを埋め込んだDeveloper Platform / tech drivers day8
chmikata
4
890
AI時代、つくる力を自分たちの手に。 ──電通×KAG、アジャイルとAI駆動開発で挑む開発の変革
yuukiyo
3
450
あなたのDartコードは丸見えかもしれない ~reFlutterで暴くFlutterアプリの中身と多層防御~
zozotech
PRO
0
740
アクセラレーターで実現するServiceNow活用の高速化 / ServiceNow World Forum 2026
visional_engineering_and_design
0
120
Devin プロモコードの受け取りと適用(2026.10.27)
kinopeee
1
820
WireGuard for Apache NuttX - Bringing Secure Remote Access to embedded Devices -
aki310ooooo
0
120
GitHub、使う?使わない?
happysamurai294
0
140
reInvent2026stby LT00 "Change your life!"
shinichirokawano
1
530
Don't write the architecture only in the prompt.
neohsu
0
290
You Have Agency(サンキュー、Ruby)
snoozer05
PRO
5
640
Featured
See All Featured
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
WCS-LA-2024
lcolladotor
0
950
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
59k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
The browser strikes back
jonoalderson
0
1.9k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Facilitating Awesome Meetings
lara
57
7.2k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
460
A Tale of Four Properties
chriscoyier
163
24k
Exploring anti-patterns in Rails
aemeredith
4
560
Transcript
%BHHFSͱ3FBMNΛ ར༻ͨ͠Ϟμϯͳ։ൃ ଜɹྋ
ࣗݾհ w ଜɹྋ w ͯͳJEGVOOFMCJU w 5XJUUFSJEFYQFSPQFSP
None
ͯͳϒοΫϚʔΫ
ژ
ࠓ͢͜ͱ w ϑϨʔϜϫʔΫ͔ΒϩδοΫΛΓ͢ w ӬଓԽ w αʔόαΠυͱฒߦͨ͠։ൃ w ϓϩμΫτνΣοΫ
ϑϨʔϜϫʔΫ͔Βϩ δοΫΛΓ͢
ϑϨʔϜϫʔΫ w "OESPJE4%,͕ఏڙ͢ΔɺΞϓϦը໘ͷϥΠ ϑαΠΫϧͱڧ݁͘ͼ͍ͭͨΫϥε
ϩδοΫΛͲ͜ʹॻ͔͘ w º"DUJWJUZ 'SBHNFOUʹॻ͘ w ංେԽɺςετෆՄೳ w ˛$VTUPN7JFXʹॻ͘ w 7JFXͷϩδοΫ͜͜ʹॻ͚ྑ͍
w ͦΕҎ֎ͷॴ
ͦΕҎ֎ͷॴʁ w ϩδοΫΛநԽͯ͠Γग़͢ w d$POUSPMMFS d.BOBHFSͳͲɺϩδοΫ୲ ΫϥεΛ࡞Δ
ϩδοΫͷநͷ*OTUBODFΛ Ͳ͜Ͱ࡞Δ͔ʁ w ˛ར༻͢Δ"DUJWJUZʹॻ͘ w ݁ͼ͖͕ͭڧ͘ͳΔ w ςετͷ࣌ʹڍಈΛม͍͑ͨͱ͖ʁ w ˓ར༻͢Δͷ֎෦Ͱੜɾཧ
w ґଘͤ͞ͳ͍ w ςετ࣌ʹΓସ͑Δɺͱ͍ͬͨ͜ͱ͕༰қ w %*
ૉͳ%* public EntryManager(APIClient apiClient) { this.mAPIClient = apiClient; ... }
ૉͳ%*͑ͳ͍ w "DUJWJUZͱ'SBHNFOUʹରͯ͠ແྗ w ίϯετϥΫλͰΠϯελϯεͤͳ͍ w 1BSDFMBCMFʹͯ͠ؤுΕͰ͖ͳ͍͜ͱͳ͍͕ ؤுΓͨ͘ͳ͍ w ͜ͷ%*ίϯςφ͕͋Εղܾ͢Δ
%*ίϯςφ w ґଘೖΛߦ͏ϑϨʔϜϫʔΫ w खಈͰΈΛ༻ҙ͠ͳͯ͘ྑ͍ w Πϯελϯεཧߦͳ͑Δ
Ͳͷ%*ίϯςφΛ͏͖ ͔ʁ w 3PCP(VJDF w %BHHFS w %BHHFS
%BHHFS
%BHHFS w IUUQTHJUIVCDPNHPPHMFEBHHFS w %*ίϯςφ w 4RVBSF͕։ൃͯͨ͠%BHHFSͷHPPHMFGPSL
%BHHFSͷར w ίϯύΠϧ࣌ʹίʔυੜ͠ґଘղܾ w ࣮ߦதͷύϑΥʔϚϯεʹӨڹ͠ͳ͍ w σόοάͰίʔυΛ͍͍͢
%*ͷߏ w .PEVMF w *OTUBODFͷੜํ๏Λهड़ w $PNQPOFOU w .PEVMFͷ*OTUBODFΛͲ͜ʹJOKFDU͢Δ͔ه ड़
w ֊ߏΛׂͨͤͯΛ୲͠໌֬Խ
.PEVMF @Module public class MainModule { ... @Provides EntryManager
provideEntryManager() { return new EntryManager(mService); } ...
$PNQPOFOU @Component(modules = MainModule.class) public interface MainComponent { void inject(MainActivity
mainActivity) …
*OKFDU public class MainActivity extends AppCompatActivity { @Inject EntryManager mEntryManager;
@Override protected void onCreate(Bundle b) { ... ((App) getApplication()) .component() .inject(this); ...
5FTU༻.PEVMF @Module public class MainTestModule { ... @Provides EntryManager
provideEntryManager() { return new EntryManager(mStubService); } ...
ςετ༻$PNQPOFOU @Component(modules = MainTestModule.class) public interface MainTestComponent { void inject(EntryManagerTestCase
testCase) …
*OKFDU ςετ public class EntryManagerTestCase extends InstrumentationTestCase { … @Inject
EntryManager mEntryManager; … public testGetEntries() { assertEquals( "ΤϯτϦऔಘͰ͖͍ͯΔ", false, mEntryManager.getEntries().isEmpty()); } }
$PNQPOFOUͷ͚ํ w "DUJWJUZ'SBHNFOUຖʹ͚Δʁ w ͕υϯυϯ૿͍͑ͯ͘ w ׂ͝ͱʹ͚Δ w ֊ߏΛ࡞ͬͯࡉԽ
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); }
4VC$PNQPOFOU @Subcomponent(modules = UserModule.class) public interface UserComponent { //
Fragments void inject(MyFragment myFragment); UserController userController(); }
$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); }
ӬଓԽ
ӬଓԽ͢Δత w 8FC"1*͔ΒͷϨεϙϯεΛӬଓԽ w ΦϑϥΠϯ༻ͷΩϟογϡσʔλͷͨΊ w "DUJWJUZ'SBHNFOUͷ࠶ੜ࣌ʹ෮ؼ͢ΔͨΊ w ෳͷը໘Ͱಉ͡σʔλΛදࣔ͢Δͱ͖ͷҰ؏ ੑΛอͪ͘͢͢ΔͨΊ
ӬଓԽ͢Δखஈ w º4IBSFE1SFGFSFODFTʹೖΕΔ w ˛'JMFʹॻ͖ͩ͢ w ˓42-JUFʹೖΕΔ w ˓3FBMNΛ͏
42-JUF w "OESPJEඪ४ͳͷͰ҆৺ײ͕͋Δ w ࣗྗͰॻ͘ͷগʑ໘͍͘͞ w 03.͏ʁ w ͍͢͞ɺૣ͞ɺ҆ఆɺকདྷੑʜ
3FBMN w ։ൃ͕׆ൃ w 42-JUFͷΑ͏ͳ໘ͳ͜ͱΛ͠ͳͯ͘ྑ͍ w ˛όʔδϣϯະຬ
3FBMNΛ͏ w J04ΞϓϦͱ ՄೳͳݶΓ ڞ௨ͷϞσϧΛ࣋ͪͨ ͍ͨΊ w ։ൃ׆ൃ͔ͩΒԿ͔͋ͬͯରॲ͞ΕΔͰ͋Ζ ͏
3FBMN
3FBMN w 42-JUFΛஔ͖͑͏Δ.PCJMFEBUBCBTF w 03.ͷػೳ࣋ͭ w ߴ w J04Ͱར༻Մೳ
3FBMNΛ͏ new RealmConfiguration.Builder(context) .name("realm") .schemaVersion(1L) .build();
3FBMNΛ͏ RealmResults<Entry> followingEntries = mRealm.where(Entry.class) .equalTo("isFollowing",true) .findAllSortedAsync( "createdAt", Sort.DESCENDING);
"DUJWJUZੜ࣌ʹҾ͘ public class MainActivity extends AppCompatActivity { … public void
onCreate(Bundle savedInstanceState) { mRealmResults = mRealm.where().findAllAsync() … } w ͙͢͞·3FBMN3FTVMUTΛಘΔ w ਖ਼͘͠෮ݩ͢ΔͨΊʹ͏
"EBQUFSʹ3FBMN3FTVMU public class EntriesAdapter { public EntriesAdapter(RealmResults<Entry> entries) { mEntries
= entries; mRealmChangeListener = new RealmChangeListener() { @Override public void onChange() { mListItems = getItems(); EpisodesAdapter.this.notifyDataSetChanged(); } }; … } …
"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); } …
"DUJWJUZؒͷσʔλड͚͠ Intent intent = new Intent(context, EpisodeActivity.class); intent.putExtra(EXTRA_ID, Id); w
3FBMNͷ*%Λ͢͜ͱʹͯ͠͠·͏ w ࠶ੜʹඋ͑ΕΔ͜ͱʹͳΔ
3FBMN Λ %BHHFS Ͱ εϨου͝ͱʹ*OKFDU
εϨου·ͨ͛ͳ͍ w 3FBMN*OTUBODF͕࡞͞ΕͨεϨου͔Βଞͷ εϨουͰ͑ͳ͍ w ͔͠͠*OKFDUPO$SFBUF Ͱߦ͍͍ͨ w ʮผεϨου͕ཉ͍࣌͠ʹ*OKFDU͢ΔΈʯ͕ ඞཁ
%BHHFSͷ1SPWJEFSΛ͏ … @Inject public EntryPrefetcher(Provider<Realm> realmProvider) extends ThreadPoolExecutor { mRealmProvider
= realmProvider; … private static class Task implements Callable<String> { @Override public String call() throws Exception { Realm realm = mRealmProvider.get(); … } …
αʔόαΠυ ͱ ฒߦͨ͠։ൃ
αʔόαΠυͱฒߦͨ͠։ൃ w "1*͕ඞͣ͠ઌߦ͢ΔͱݶΒͳ͍ w μϛʔσʔλΛΞϓϦ෦ʹ͔࣋ͭʁ w "1*ʹมߋ͕͋ͬͨ࣌ʹ໘ w J04ଆಉ࣌ʹมߋ͢Δඞཁ͕ग़ͯ͘Δ
4UVC4FSWFS
4UVC4FSWFS w μϛʔͷϨεϙϯεΛฦ͢αʔόΛ࡞Δ w "1*4DIFNB όϦσʔλͱͯ͠ར༻ w IUUQTHJUIVCDPNIJUPEF"1*4DIFNB
4UVC4FSWFS SFTPVSDFMPHJO@SFRVFTU\ UZQFPCKFDU EFTDSJQUJPOϩάΠϯϦΫΤετ QSPQFSUJFT\ FNBJM@BEESFTT\ UZQFTUSJOH
EFTDSJQUJPOϝʔϧΞυϨε FYBNQMFBCD!FYBNQMFDPN ^ QBTTXPSE\ UZQFTUSJOH EFTDSJQUJPObύεϫʔυ FYBNQMF1BTTXSE ^ ^ SFRVJSFE<FNBJM@BEESFTT QBTTXPSE> ^
ςετͰ4UVC4FSWFSΛ ͏ w ˛μϛʔͷ+40/Λ෦ʹ࣋ͬͯςετʹར༻ w "1*มΘΔͨͼʹมߋͤͶͳΒͳ͍ w "1*ͷมߋʹςετ͕ؾ͚ͳ͍ w ̋"1*ͷαʔόΛୟ͘
w μϛʔσʔλෆཁ w มߋʹςετ͕ؾ͕ͭ͘
ϓϩμΫτνΣοΫ
ϓϩμΫτνΣοΫ w ژɾ౦ژʹΦϑΟε͕͋Δ w ౦ژʹσβΠφʔ͕͍Δ w ख৮Γ৮Εͳ͍ͱΘ͔Βͳ͍
#FUB#Z$SBTIMZUJDT KFOLJOT GBTUMBOF
#FUB w #FUB#Z$SBTIMZUJDTΛͬͯ#FUB৴ w ৴ͷλΠϛϯάKFOLJOTʹͤΔ
KFOLJOT w ϒϥϯνΛݟͯͯɺNBTUFSʹϚʔδ͞ΕͨΒ #FUBΛඈ͢ w εΫϦʔϯγϣοτΛࡱͬͯ؆қతͳσβΠϯ֬ ೝ w "1*ຖͷࠩҟΛ֬ೝ w
4MBDLʹ௨
GBTUMBOF (JUIVC࿈ܞ EBUB\TUBUFTUBUF UBSHFU@VSMUBSHFU@VSM DPOUFYUDPOUFYU EFTDSJQUJPO^ IFBEFST\"VUIPSJ[BUJPOUPLFO\UPLFO^^ &YDPOQPTU VSM
IFBEFSTIFBEFST CPEZ EBUBUP@KTPO
GBTUMBOF 4MBDL࿈ܞ TMBDL NFTTBHFSPDLFUϏϧυ͕ྃ͠·ͨ͠SPDLFU DIBOOFMBQQ TVDDFTTUSVF
QBZMPBE\ #VJME%BUF5JNFOFXUP@T ^ EFGBVMU@QBZMPBET<HJU@CSBODI HJU@BVUIPS>
ςετ࣮ߦ EFTD3VOTBMMUIFUFTUT MBOFUFTUEP HSBEMF UBTLD$ FOE
·ͱΊ w ϑϨʔϜϫʔΫ͔ΒϩδοΫΛΓ͢ w ϩδοΫͷநԽɺ%BHHFSͰ*OKFDU w ӬଓԽ w 3FBMNΛར༻ w
αʔόαΠυͱฒߦͨ͠։ൃ w 4UVC4FSWFSΛར༻ w ϓϩμΫτνΣοΫ w #FUB#Z$SBTIMZUJDT KFOLJOT GBTUMBOF
͋Γ͕ͱ͏͍͟͝·ͨ͠