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
tab for Androidの作り方
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
lychee
April 24, 2014
Technology
400
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
tab for Androidの作り方
lychee
April 24, 2014
More Decks by lychee
See All by lychee
Android開発者とデザイナーの効果的な連携に効く話
superdry
0
78
はじめてのぐーぐるあいおー
superdry
0
160
Other Decks in Technology
See All in Technology
日本語に強いオープンな大規模言語モデル「LLM-jp」
odashi
4
1.1k
20261017福岡devIO 「AIは"良いダッシュボード"を作れるか?
jtakeda
0
140
パスキーの自動テストはどこまでいけるのか
teamlab
PRO
0
200
Claude Code本は、どのように執筆チームで書かれたか
oikon48
1
380
AIがコードを書く時代に、エンジニアは何で自分の価値を証明するのか / In an era where AI writes code how do engineers prove their value
carta_engineering
3
1.1k
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
330
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
440
オントロジーって 結局なにもの? AI エージェントに「意味」を渡す知識設計の話
greenmidori
0
180
Rust で関数型ドメインモデリング
takonda
0
140
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.3k
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
Active Record Connection Adaptersにおける長年の課題に再び取り組む
yahonda
0
140
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
280
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
570
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
280
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
So, you think you're a good person
axbom
PRO
2
2.2k
Transcript
tab for Androidͷ࡞Γํ Yasuyo Nishioka (tab Inc.) 2013/4/24
tab for Android • 2013/2 ։ൃ։࢝ • ݱࡏ1.9.3൛ • ։ൃମ੍2໊
• ϦϦʔε݄2ʙ4ϖʔε • ରԠൣғɿAPI Ϩϕϧ 10(2.3.3)Ҏ্ • ࡉʑͱͬͯ·͢ ΤϯδχΞืूதʂ
ࠓ͢͜ͱ • ։ൃπʔϧ • ΞϓϦͷߏͱ༻ϥ ΠϒϥϦ • API௨৴෦ • JSONύʔα
• Model • ը໘දࣔ • ͦͷଞϥΠϒϥϦ • ςετ
։ൃπʔϧ
։ൃπʔϧ • IDE • Eclipse • Android StudioʹҠ ߦத •
ϦϙδτϦ • GitHub Enterprise • CI • Jenkins @AWS • ࣾςετ • DeployGate
πʔϧͷ࿈ܞ ᶃpush ᶄpull ᶅbuild ᶆupload ᶇdownload ᶈdogfooding
ͦͷଞπʔϧ • A/Bςετ • Apptimize • Ҋ݅ཧ • Pivotal Tracker
• όάཧ • Bugsense • ίϛϡχέʔγϣϯ • Hipchat
Apptimize
Pivotal tracker
Bugsense
Hipchat Bugsense Pivotal Jenkins Github ͱ࿈ܞ
ΞϓϦͷߏͱ༻ϥΠϒϥϦ
"1*௨৴෦ • ϥΠϒϥϦ:Android Async Http Client • ࣌Volley͕ͳ͔ͬͨ • ը૾μϯϩʔυܥAPI͔ͭͬͯͳ͍
(ޙड़) • AsyncHttpResponseHandleΛ֦ு͠REST APIίʔϧ͔ΒJSONύʔεͯ͠ModelΦϒ δΣΫτͱͯ͠อ࣋͢Δ·ͰҰ؏ͰΕΔ Α͏ʹ͍ͯ͠Δɻ
ʢྫʣ"1*௨৴෦ public static void get(int id, final OnPostListener<ItemObject> listener) {
String pathString = String.format("items/%d.json", id); tabRestClient.execute( pathString, null, new TabApiResponseHandler<ItemObject>(listener)); }
ྫʣσʔλऔಘ Item.get(itemId, new OnPostListener<ItemObject>() { @Override public void onError(Throwable e,
Error error) { //Τϥʔॲཧ } @Override public void onCompletion(ItemObject response) { Item item = response.getItem(); // Α͠ͳʹ } });
Model • ϥΠϒϥϦ:Lombok • ίʔυྔݮ • BundleʹͭΊΕΔΑ͏ʹSerializableΛܧঝ • ઌ΄Ͳͷσʔλऔಘͷॲཧ͜ͷΫϥεʹ ࣮
ίʔυྔͷൺֱ import lombok.Data; @Data public class Item implements Serializable {
public static final String KEY = "item"; /** Response */ private int id; private String title; private String description; public static void get(int id, hogehoge...){ //͖ͬ͞ͷίʔυ } } public class Item implements Serializable { public static final String KEY = "item"; /** Response */ private int id = Models.INVALID_INT; private String title; private String description; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public static void get(int id, hogehoge...) { //͖ͬ͞ͷίʔυ } }
JSONύʔα • ϥΠϒϥϦ: Jackson • Jackson/GSON/JSONIC Ͱϕϯνͱ ͬͯൺֱ • ඇಉظॲཧ͢ΔΑ͏֦ு
ը໘දࣔ ྫ1) ͲΜͲΜͰͯ͘ΔΑ ϖʔδωʔγϣ ϯɾϓϦϩʔυ 2ྻදࣔ Pull to Refresh
Loader/Adapter • LoaderࣗಈͰϖʔδωʔγϣϯ͢ΔΑ͏֦ு • AdapterϓϦϩʔυΛ͢ΔΑ͏֦ு • GenericsͰڞ௨Խ
Loader/Adapter <<abstract>> BaseAdapter <<abstract>> AbstractLoaderAdapter CustomAdapter CustomPairLayout Adapter <<abstract>> AbstractDataLoader
<<interface>> DataLoader CustomLoader Activity, Fragment <<create>> <<create>> <<interface>> DataLoaderListener
ʢྫʣLoader public class ItemLoader extends AbstractDataLoader<Item> { @Override protected void
onLoadPage(int page, int limit, OnPostListener<? extends PaginatedResponse<Item>> listener) { Item.list(page, limit, (OnPostListener<PaginatedItems>) listener); } }
ʢྫʣAdapter public class ItemAdapter extends AbstractLoaderAdapter<ItemLoader> { public ItemAdapter(ItemLoader loader,
Context context) { super(loader, context); reload(); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Α͠ͳʹ } }
Pull to refresh ListView • ༻ϥΠϒϥϦ: Pull to Refresh
ListView • ࣌ActionBar-PullToRefresh SwipeRefreshLayoutͳ͔ͬͨ • ܰྔ • GridView͕͑ͳ͍ • ͋·Γϝϯςφϯε͞Εͯͳ͍ͷͰɺҰ෦ SwipeRefreshLayoutʹҠߦத • ϑολʔʹϩʔσΟϯάΞχϝʔγϣϯΛදࣔ͢ ΔΑ͏֦ு
ը૾μϯϩʔυ • ༻ϥΠϒϥϦ: Universal Image Loader • ࠷ॳSmartImageViewΛ͍͕ͬͯͨɺͪ͜ Βͷํ͕ɺΦϓγϣϯ͕๛(σΟϨΠදࣔɺ ؙ֯ɺΩϟογϡͳͲ)ͰΧελϜ͍͢͠
• inMemory/onDiskͰΩϟογϡ • ؙ֯ॏ͍ͷͰ֎ͨ͠
ը໘දࣔ ྫ2) ·ͩ·ͩ͋ΔΑ ɹػೳ͕Γͩ͘͞Μ ฤूɺআɺίϐʔɺҠಈɺڞ༗ɺ tabாϑΥϩʔɺ༧ɺϦΫϦοϓɺಛయද ࣔɺใදࣔɺళฮใදࣔɺϚοϓɾϧʔ τݕࡧɺ ผΞΠςϜͷαδΣετɺϦΫϦοϓҰ ཡɺίϝϯτ…
• ॳ1Fragment͕ͩͬͨlistenerͩΒ͚ ʹͳͬͯ͠·͍ϝϯςφϯε͕ࠔʹ • Nested Fragmentʹ͏͜Γ͝Γ • Event busΛ͏͜ͱʹ
Event Bus • ༻ϥΠϒϥϦɿSquare Otto • Activity-Fragmentؒɺ֤Fragmentؒͷ௨ʹ༻ • Fragmentͷָׂ͕ʹˍListenerࠈ͔Βղ์ •
Weak Reference ͬͯunregister͠ͳ͍͍ͯ͘Α͏ʹ ֦ு
ͦͷଞ༻ϥΠϒϥϦ • Android-ViewPagerIndicator • Android-MenuDrawer • ArcMenu/SwitchCompatLibrary • Google Play
Service • GridLayout • Facebook SDK • Twitter4j • OrmLite ... ଟ͗ͯ͢ɺ ϝιου্ݶʹ Ҿ͔͔ͬΔ
ϝιου্ݶ • ݱ • ಛఆͷ2.3ܥͰىಈͰ͖ͳ͍ • Error while installing application
(INSTALL_FAILED_DEXOPT) • ݪҼ • ϝιου͕65536Ҏ্ʹͳΔͱDexoptͷ ͏όοϑΝαΠζΛ͑Δ
ରॲ • ϥΠϒϥϦΛεϦϜʹ • ͋·Γͬͯͳ͔ͬͨGuavaΛ֎͢ • GooglePlayServicesͱAnalyticsͷϥΠϒϥϦ Λซ༻͠ͳ͍ • ຊདྷ...
• ProGuardͰ࠷దԽ • dexϑΝΠϧΛׂ͠ΧελϜΫϥεϩʔσΟ ϯά • Facebookϒϩάͱ͔
ςετ
ςετ • ༻ϥΠϒϥϦɿMockito + Roboguice • ςετϙϦγʔ • ௨৴෦ɾModelɾLoaderςετඞਢ •
API௨৴෦Λmock/spyͯ͠ਖ਼ৗ/ҟৗܥ Ұ௨Γ
՝ • γφϦΦςετΛ͍ͨ͠ • RobotiumΛͬͯγφϦΦςετ࣮͠ ͕ͨɺ҆ఆ͠ͳ͍ҝ͍ͣͯ͠Δ • Espresso? • final/staticϝιουͰϞοΫͰ͖ͳ͍
• PowerMock?
͓͠·͍ ΤϯδχΞืूதʂ