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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
300
BottomBarAndSnackBar
funnelbit
0
550
Dagger2 Optional bindings
funnelbit
0
620
WearableRecyclerView
funnelbit
1
850
QucikSettingsTileAPI
funnelbit
0
390
Mobile Vision
funnelbit
0
490
AwarenessAPI
funnelbit
0
170
Other Decks in Technology
See All in Technology
LTのテーマ どうきめてる?〜5つの型と私のやり方〜
yama3133
1
110
すぐできる衛星通信対応 あとは山奥に行くだけ
tatetate55
0
130
現場で役立つ技術負債の効果的な返済方法
masuda220
PRO
9
4.4k
AIエージェントの一手は 誰も見ていない - Falco拡張OSS「Prempti」とeBPFで サーバーレス実行基盤を二層防御する
keitah
0
120
Minecraft JavaのMODをSwiftで作る
1mash0
0
170
EventBridge に「合流」はない ― サーバーレスのワークフローを育てるということ / No Join in EventBridge
yusukeshimizu
2
110
aws-iot-platform-architecture-use-cases.pdf
ma2shita
0
260
白金鉱業Meetup Vol.25 アウトカムが二値のデータに対するCausal Impact
brainpadpr
0
220
AIによるクリエイティブ生成を行う上での試行錯誤
plaidtech
PRO
0
160
「守り」で活用するオンデバイスLLM 〜写ってはいけないを総力戦で防ぐ〜 / iOSDC Japan 2026
nakamuuu
0
170
AIを活用するために決めた "やらないこと" - 価値に注目する / Not betting on AI
soudai
PRO
2
550
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
160
Featured
See All Featured
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.9k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
From π to Pie charts
rasagy
1
370
Exploring anti-patterns in Rails
aemeredith
4
510
Producing Creativity
orderedlist
PRO
348
41k
Crafting Experiences
bethany
1
340
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
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
͋Γ͕ͱ͏͍͟͝·ͨ͠