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
How to keep data between orientation changes
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Masaki Ogata
April 20, 2017
Programming
2.7k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
How to keep data between orientation changes
AbemaTVで実装している画面回転を支えるデータ保持についての話
Masaki Ogata
April 20, 2017
More Decks by Masaki Ogata
See All by Masaki Ogata
Jetpack Composeで始めるServer Cache State
ogaclejapan
2
330
AbemaTVを支えるアプリの優しさ / abematv_devcon_2017
ogaclejapan
3
6.9k
Architecture Components - Lifecycle library
ogaclejapan
3
2.9k
Your app name
ogaclejapan
1
3k
Flux de Relax :)
ogaclejapan
13
62k
Dagger2 has been released!
ogaclejapan
3
3.4k
Other Decks in Programming
See All in Programming
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
120
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.2k
wkhtmltopdfの次どうするか問題2026
willnet
1
100
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
130
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
110
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.8k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
100
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
480
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
280
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.2k
What We Talk About When We Talk About XP
m_seki
2
630
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
150
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Designing for humans not robots
tammielis
254
26k
Exploring anti-patterns in Rails
aemeredith
4
510
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Believing is Seeing
oripsolob
1
220
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
500
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
480
Navigating Weather and Climate Data
rabernat
0
520
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
740
How STYLIGHT went responsive
nonsquared
100
6.3k
The SEO Collaboration Effect
kristinabergwall1
1
560
Transcript
CA.apk #2 @CyberAgent Masaki Ogata ը໘ճసΛࢧ͑Δσʔλอ࣋ :)
ࣗݾհ Masaki Ogata CyberAgent, Inc. / AbemaTV, Inc. ogaclejapan @ogaclejapan
New
20174݄11ൃച ࢁށໜथɼࡔాߊҰɼࠇ༸ɼ౻ా ୖຏɼࢁాߤɼాࡔெɼ۽୩ࢠɼ ຊརതɼࡔຊେɼখܗণथɼླ େوɼࢤำါلɹஶ B5ʗ192ϖʔδ ఆՁʢຊମ1,980ԁʴ੫ʣ ISBN 978-4-7741-8863-8 https://goo.gl/Jcy3lJ
New
ը໘ճసΛࢧ͑Δσʔλอ࣋ :) by AbemaTV
2017/4 ॎରԠϦϦʔε͠·ͨ͠
Կ͕มΘͬͨͷ͔ʁ
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tv.abema" > ... <activity android:name=".components.activity.MainActivity" android:configChanges="orientation|keyboardHidden| screenSize" android:screenOrientation="sensorLandscape"
android:theme="..." /> ... </manifest> AndroidManifest.xml
AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tv.abema" > ... <activity android:name=".components.activity.MainActivity" android:configChanges="orientation|keyboardHidden| screenSize"
android:screenOrientation="sensorLandscape" android:theme="..." /> ... </manifest>
AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tv.abema" > ... <activity android:name=".components.activity.MainActivity" android:screenOrientation="behind" android:theme="..."
/> ... </manifest>
Activity࠶ੜͱ ৽͍͠ੜ׆࢝Ί·ͨ͠$
ཧ༝̍ɿॎʗԣͰ࠷దͳUIΛ࣮ݱ͍ͨ͠
ཧ༝̎ɿMultiWindowʹରԠ͍ͨ͠
Activity࠶ੜԿ͕ͳͷ͔ʁ
Activity࠶ੜͷɿ • ϨΠΞτঢ়ଶͷ෮ݩ ʢChannelɺFullscreenɺ…ʣ • αʔόʔ͔Βऔಘͨ͠σʔλͷ࠶ར༻ • ॎʗԣͷը໘Γସ͑ͷγʔϜϨε͞
ҰൠతͳΞϓϩʔν
onSaveInstanceState(..)ͰBundleอଘ public class MainActivity extends AppCompatActivity { @Override protected void
onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("foo", foo); ... } @Override protected void onCreate(Bundle savedInstanceState) { ... if (savedInstanceState != null) { Foo foo = savedInstanceState.getParcelable("foo"); }
(‘A`)ΫιΊΜͲͤ͐͘ʔʂ
AbemaTVͷΞϓϩʔν
onRetainCustomNonConfigurationInstance()ͰObjectฦ͢ public class MainActivity extends AppCompatActivity { @Override public Object
onRetainCustomNonConfigurationInstance() { return foo; } @Override protected void onCreate(Bundle savedInstanceState) { ... Object obj = getLastCustomNonConfigurationInstance(); if (obj instanceof Foo) { Foo foo = (Foo) obj; }
͜Εͩ! ! ‷( ŋŷŋ)و ̑̑ ŞƄŕ !
ͪΐͬ͜ͱιʔείʔυΛͬͯΈͨ
FragmentActivity.java public Object onRetainCustomNonConfigurationInstance() { return null; } @Override public
final Object onRetainNonConfigurationInstance() { ... Object custom = onRetainCustomNonConfigurationInstance(); ... NonConfigurationInstances nci = new NonConfigurationInstances(); nci.custom = custom; nci.fragments = fragments; nci.loaders = loaders; return nci; }
Activity.java public Object onRetainNonConfigurationInstance() { return null; } NonConfigurationInstances retainNonConfigurationInstances()
{ Object activity = onRetainNonConfigurationInstance(); ... NonConfigurationInstances nci = new NonConfigurationInstances(); nci.activity = activity; nci.children = children; nci.fragments = fragments; nci.loaders = loaders; ... return nci; }
ActivityThread.java public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { return
performDestroyActivity(token, finishing, 0, false); } private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance) { ActivityClientRecord r = mActivities.get(token); ... if (getNonConfigInstance) { try { r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances(); ...
ActivityThread.java private void handleRelaunchActivity(ActivityClientRecord tmp) { ... handleDestroyActivity(r.token, false, configChanges,
true); ... ... handleLaunchActivity(r, currentIntent, ".."); ... } private Activity performLaunchActivity(...) { activity.attach(appContext, ..., r.lastNonConfigurationInstances, ...); ... r.lastNonConfigurationInstances = null;
Configuration ChangeʹΑΔ Activity࠶ੜ࣌ͷΈ෮ݩՄೳ
AbemaTVͰ Ͳ͏࣮͍ͯ͠Δͷ͔ʁ
AbemaTVͷΞʔΩςΫνϟɿ https://speakerdeck.com/ogaclejapan/flux-de-relax
AbemaTVͷFluxΞʔΩςΫνϟɿ
ը໘ճసͰഁغͤ͞ͳ͍DaggerͷComponentΛؚΊΔ @Override public ScreenComponent getScreenComponent() { if (screenComponent == null)
{ ScreenInstance retainedInstance = (ScreenInstance) getLastCustomNonConfigurationInstance(); if (retainedInstance == null) { ... screenComponent = Components.forApp(this).plus(...); } else { screenComponent = retainedInstance.component; } } return screenComponent; } @Override public Object onRetainCustomNonConfigurationInstance() { return new ScreenInstance(screenComponent, ...); }
AbemaTVͷDIίϯϙʔωϯτߏɿ AppComponent: ʢશମʣ ScreenComponent: ʢը໘୯Ґʣ ActivityComponent: ʢը໘୯Ґʣ ը໘ճసΛӽ͑ͯσʔλΛอ࣋͢ΔͨΊʹ ScreenίϯϙʔωϯτΛՃɻ
Activity࠶ੜͷɿ •ϨΠΞτঢ়ଶͷ෮ݩ ʢChannelɺFullscreenɺ…ʣ • αʔόʔ͔Βऔಘͨ͠σʔλͷ࠶ར༻ • ॎʗԣͷը໘Γସ͑ͷγʔϜϨε͞
͓ΘΓʹ /** * Return the value previously returned from *
{@link #onRetainCustomNonConfigurationInstance()}. */ @SuppressWarnings("deprecation") public Object getLastCustomNonConfigurationInstance() { NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); return nc != null ? nc.custom : null; } d..deprecation!??
͞ͱϦεΫࢴҰॏ