Upgrade to Pro — share decks privately, control downloads, hide ads and more …

さて、Android アプリのパフォーマンスを上げる方法について語りますか(ディレクターズ・カ...

さて、Android アプリのパフォーマンスを上げる方法について語りますか(ディレクターズ・カット版)

関西モバイルアプリ研究会 #14 Android 発表枠のライトニングトークで使用したスライドです ⬇︎
http://kanmoba.connpass.com/event/31750/

「Android ViewGroup ネスト」で検索すると @konifar さん著の為になる記事がありました ⬇︎
http://qiita.com/konifar/items/3c75f1fab0e0a10ebb14

動画は https://vimeo.com/168086902 にアップロードしました。

⬇︎⬇︎ 以下、テンパって見ることができなかった Keynote の発表者ノート ⬇︎⬇︎

発表内容は

・ViewGroup を入れ子にし過ぎるのは良くない
・アプリを高速化する方法
について
です。

ViewGroup とはレイアウトの外枠みたいなもの。
その中に TextView や ImageView などのウィジェットを入れて配置していく。
ViewGroup の
種類は LinearLayout や RelativeLayout など。

注意点は ViewGroup をネストさせるとアプリの動きが重くなること。

今回の発表のために ViewGroup ネストでアプリが重くなることが一目で分かる動画を作ってみました。
手順は ViewGroup 1階層と100階層の ListView を準備して
 adb の input touchscreen swipe コマンドで両方のリストを同じ力でスクロールしたものを
 adb の screenrecord で録画するという方式です。

【11ページを見ながら説明】
左がスイスイ動く、右は動きがガタガタしています。

動画で違いが分かりにくいという方は
実際に端末でやってみると重さを実感できます。

若干脱線しますが動画を作ってみて得た知見。
Android 4系では ViewGroup を20階層ぐらいネストするとエラーで落ちますが、5系では100階層ネストしても落ちないということが分かりました。

最新バージョンはやはりスペックが高い。

続いて
、無駄に ViewGroup を入れ子にしているところを減らしてアプリのパフォーマンスをUPする方法について。

① PercentRelativeLayout
PercentRelativeLayout の特徴は配置するウィジェットのサイズを「
ディスプレイ全体の縦横何パーセント」で決めることができるところです。

レイアウトを作るときは先ずコレを使うこと考えた方が得策だと思います。

PercentRelativeLayout を使わなかった場合、
ViewGroup を結構多めに使う羽目になるというのが経験上&体感的にあります
。
PercentRelativeLayout を使うと少なめの ViewGroup で結構凝ったレイアウトが作れたりします。

② merge タグ
ViewGroup のカスタムビューを作るときに xml のルートを merge タグにしましょう。
なぜなら extends している ViewGroup のクラスがルート部分を担っているので merge タグで省略できます。

【19ページを見ながら説明】
PercentRelativeLayout を extends しているカスタムビューです。

【20ページを見ながら説明】
この xml のルート部分に merge タグを使っているので無駄に1階層増えずに済んでいます
(ここの merge タグを ViewGroup にした場合は無駄に ViewGroup が生成されてしまうことになる)

◆ まとめ ◆
・ViewGroup のネストを減らすとアプリがスイスイ動くようになる
・ソースコードが結構見易くなる
・PercentRelativeLayout と merge タグを使って ViewGroup のネストを減らしましょう

Hashido Tomoya

May 25, 2016
Tweet

More Decks by Hashido Tomoya

Other Decks in Programming

Transcript

  1. ڮ౓๎໻ʢ͸͠Ͳͱ΋΍ɺ1990೥7݄15೔ - ʣ ࣗݾ঺հ • ژ౎ࢢ੢ژ۠ ࡏॅʢ࣮Ոʣ • Android ྺɿ4.0

    (Ice Cream Sandwich) ͕࠷৽όʔδϣϯͩͬͨࠒ͔ Β • ಛٕɿ48/46άϧʔϓͷݸମࣝผ • ࠷ۙѲखձʹߦͬͨਓɿਢ౻႒ʑՖʢNMB48ʣ
 ఩ֶຊͷൢଅΠϕϯτˏάϥϯϑϩϯτେࡕ 2
  2. 2016೥10݄15೔(౔) શࠃ౦ๅܥϩʔυγϣʔ өըʰԿऀʱʹөΓࠐΜͰ͍Δ͔΋ʁ • ݪ࡞ɿேҪϦϣ΢ • ʰۅౡɺ෦׆΍ΊΔͬͯΑʱ • ʰνΞஉࢠ!!ʱ •

    ʰ෢ಓؗʱ • ʰ··ͳΒͳ͍͔Βࢲͱ͋ͳͨʱ
 • ؂ಜɾ٭ຊɿࡾӜେี • ʰϘʔΠζɾΦϯɾβɾϥϯʱ • ʰѪͷӔʱ 3
  3. ViewGroup ͷऔΓѻ͍ .xml ϨΠΞ΢τ࡞੒࣌ͷ஫ҙ఺ • ViewGroup ͷछྨ • LinearLayout •

    RelativeLayout • FrameLayout • ViewGroup Λଟ༻ͯ͠ϨΠ Ξ΢τͷ֊૚Λਂ͘͢Δͱը ໘ͷදࣔ଎౓͕஗ΕͨΓɺε Ϋϩʔϧ͕ΨλΨλ͢ΔͳͲ ͷฐ֐͕ੜ͡·͢ 8
  4. ʙImageView Λදࣔ͢Δ .xml ϨΠΞ΢τͷαϯϓϧʙ ViewGroup Λωετ͢ΔͱύϑΥʔϚϯε͕௿Լ <?xml version="1.0" encoding="utf-8"?>
 


    <LinearLayout xmlns:android="http:// schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
 
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <ImageView
 android:id="@+id/imageView"
 android:layout_width="match_parent"
 android:layout_height="400dp"
 android:scaleType="centerCrop" />
 </LinearLayout>
 </LinearLayout>
 </LinearLayout>
 </LinearLayout> 9 <?xml version="1.0" encoding="utf-8"?>
 
 <LinearLayout xmlns:android="http://schemas.android.com/ apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
 
 <ImageView
 android:id="@+id/imageView"
 android:layout_width="match_parent"
 android:layout_height="400dp"
 android:scaleType="centerCrop" />
 
 </LinearLayout> ྑ͍ྫ ˕ LinearLayout ͕ 1 ֊૚ ѱ͍ྫ × LinearLayout ͕ ແବʹ 4 ֊૚
  5. ʙؔ੢ϞόΠϧΞϓϦݚڀձ#14 LT༻ʹݕূಈըΛ࡞ͬͯΈΔʙ ViewGroup Λωετ͢ΔͱύϑΥʔϚϯε͕௿Լ 10 εΫϩʔϧॲཧ͕ॏ͘ͳΔ͜ͱ͕Ұ໨Ͱ෼͔Δಈը 
 खॱɿ 1.ηϧͷ ViewGroup

    ͕1֊૚ͱ100֊૚ͷ ListView ΞϓϦΛ࡞੒ 2.λʔϛφϧͰ adb shell screenrecord /sdcard/video.mp4 ࣮ߦͯ͠ ୺຤ͷը໘Λ࿥ը͢Δ 3.શ͘ಉ͡੎͍ͰεΫϩʔϧ͢ΔͨΊʹλʔϛφϧ͔Β adb shell input touchscreen swipe x1 y1 x2 y2 Λ࣮ߦ͢Δ 4.iMovie ͷʮεϓϦοτεΫϦʔϯʯͰ2ͭͷಈըΛฒ΂ͨ΋ͷΛ1 ͭͷಈըͱͯ͠อଘ͢Δ
  6. ͦͷଞʹಘͨ஌ݟʢ୤ઢؾຯʣ ViewGroup ೖΕࢠͷൺֱಈըΛ࡞ͬͯΈͯ • Android 5.0 ܥ (Lollipop) Ͱ͸ LinearLayout

    Λ໿100֊૚ೖΕࢠʹ͠ ͯ΋ StackOverflow ΤϥʔͰڧ੍ऴྃ͠ͳ͍ • Android 4.x ܥҎԼͰ͸ LinearLayout ͷೖΕࢠ20֊૚Ҏ಺Ͱ StackOverflow Τϥʔൃੜ • Android 5.0, 6.0 ܥͰ͸ ViewGroup Λଟ༻ͯ͠΋ಈ࡞͸ׂͱ͍ܰ
 ʢωετͷӨڹΛड͚ʹ͍͘ʣ
 ʢͱ͍͏͔ݩʑૉૣ͘ಈ͘ʣ 12
  7. ͦͷᶃ PercentRelativeLayout ViewGroup ͷ࡟ݮํ๏ • ଟػೳʹͳͬͨ RelativeLayout • LinearLayout ͷ

    layout_weight ૬౰ͷ΋ͷ͕ RelativeLayout Ͱ ࢖͑ΔʢαΠζΛ%Ͱࢦఆʣ ྫʣɹ
 <TextView app:layout_widthPercent="100%"
 app:layout_heightPercent="20%" /> 15
  8. ͦͷᶃ PercentRelativeLayout ViewGroup ͷ࡟ݮํ๏ • LinearLayout ͱ FrameLayout ͔͠࢖Θͳ͍റΓͰෳࡶͳσβΠϯͷ ϨΠΞ΢τΛ࡞Ζ͏ͱͨ͠৔߹


    ˠ ؤுͬͯ ViewGroup ͷ࢖༻Λ཈͑Α͏ͱͯ͠΋ଟॏʹωετ͠ ͯ͠·͏ 1֊૚Ͱ࡞Ζ͏ͱ͢Δͱݶք͕དྷΔ • PercentRelativeLayout Λ࢖༻ͨ͠৔߹
 ˠ PercentRelativeLayout 1֊૚ͰෳࡶͳσβΠϯͷϨΠΞ΢τ͕࠶ ݱͰ͖ΔՄೳੑ͕͋Δ 16
  9. ͦͷᶄ merge λά ViewGroup ࡟ݮํ๏ • ViewGroup Λ extends ͨ͠ΧελϜϏϡʔͰ

    .xml Λ࢖༻ͯ͠
 ϨΠΞ΢τશମΛ࡞੒͢Δ৔߹ .xml ͷ1൪֎ଆ͸ merge λάʹ
 ͠·͠ΐ͏ ⭐ • ͜ͷ .xml ͷ1൪֎ଆΛ ViewGroup ʹͯ͠͠·͏ͱɺ1֊૚ແବʹ ViewGroup ͕૿͑ͯ͠·͏͜ͱʹͳΓ·͢ ☠ 18
  10. ͦͷᶄ merge λάɿJava ଆαϯϓϧίʔυ ViewGroup ࡟ݮํ๏ 19 package jp.co.sample.package;
 


    import android.content.Context;
 import android.support.percent.PercentRelativeLayout;
 import android.util.AttributeSet;
 import android.view.View;
 
 /**
 * merge λάΛ࢖༻ͨ͠ΧελϜϏϡʔ
 */
 public class SampleCustomView extends PercentRelativeLayout {
 
 public SampleCustomView(Context context) {
 this(context, null);
 }
 
 public SampleCustomView(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }
 
 public SampleCustomView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 View.inflate(context, R.layout.custom_view, this);
 }
 } SampleCustamView.java
  11. ͦͷᶄ merge λάɿ.xml ଆαϯϓϧίʔυ ViewGroup ࡟ݮํ๏ 20 <?xml version="1.0" encoding="utf-8"?>


    
 <merge xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 
 <TextView
 android:id="@+id/textView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerHorizontal="true"
 android:text="ԡͯ͠Ͷ!" />
 
 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_below="@id/textView"
 android:text="Ϙλϯ" />
 </merge> custom_view.xml
  12. ϨΠΞ΢τͷ ViewGroup ֊૚Λઙ͘͢ΔϝϦοτ ·ͱΊ • Android 4.x ܥҎԼͷ৔߹͸ಛʹΞϓϦͷύϑΥʔϚϯε͕ྑ͘ͳΔ • ViewGroup

    Λ1֊૚࡟ݮ͚ͨͩ͠Ͱ΋ޮՌ͕ग़Δ • .xml ͷίʔυ͕ಡΈқ͘ͳΔ • .xml ͷωετ͕ઙ͍ͱ௥͍͔͚қ͍Ͱ͢ 21 ViewGroup ͷ۩ମతͳ࡟ݮํ๏ • PercentRelativeLayout • merge λά
  13. ࣭ٙԠ౴ᶃ ʮؔϞό #14ʯൃදऴྃޙ • Q: ࣮ྫͱͯ͠Կ֊૚͙Β͍ͷϨΠΞ΢τͰ ViewGroup Λ࡟ݮͯ͠ ͲΕ͘Β͍ߴ଎Խͨ͠ʁ •

    A: ViewGroup ͕ 4ɺ5֊૚ωετͨ͠ ListView ͷϨΠΞ΢τ͔Β 1 ֊૚࡟ݮ͢ΔͱεΫϩʔϧ͕ҎલΑΓܰ͘ͳͬͨͱ෼͔Δ͙Β͍ 23
  14. ࣭ٙԠ౴ᶄ ʮؔϞό #14ʯൃදऴྃޙ • Q: RelativeLayout Ͱ͸μϝͳΜͰ͔͢ʁ PercentRelativeLayout ͷ Ͳ͕͍͍͜ΜͰ͔͢ʁ

    • A: PercentRelativeLayout ͸ RelativeLayout ͷੑೳ ʴ TextView ౳ ΢ΟδΣοτͷαΠζΛॎԣύʔηϯτࢦఆͰ͖ΔͷͰ 1 ֊૚Ҏ಺ Ͱ࡞੒Ͱ͖ΔσβΠϯͷόϦΤʔγϣϯ͕૿͑Δ͸ͣ 24
  15. ࣭ٙԠ౴ᶅ ʮؔϞό #14ʯൃදऴྃޙ • Q: ൃදͰ͋ͬͨಈըҎ֎Ͱ ViewGroup ࡟ݮͷޮՌΛଌఆͰ͖Δํ ๏͸͋Γ·ͤΜ͔ʁ •

    A: ౰೔͸υ๨Εͯ͠౴͑ΒΕ·ͤΜͰ͕ͨ͠ɺݕࡧͯ͠ࢥ͍ग़͠· ͨ͠ɻHierarchy Viewer Λ࢖͏ͱϨΠΞ΢τ࡞੒·Ͱʹ͔͔ͬͨ࣌ ͕ؒදࣔ͞ΕΔΑ͏Ͱ͢ 25
  16. ͦͷᶃ աڈͷաͪ • େֶੜ࣌୅ʹ RelativeLayout Ͱ࠳ંͨͨ͠ΊɺҎ߱ LinearLayout ͱ FrameLayout ͔͠࢖Θͳ͘ͳΔ

    • ʮ layout_above, layout_below Λ
 ͪΌΜͱઃఆ͍ͯ͠Δ͸ͣͳͷʹ
 ࢥͬͨ௨Γදࣔ͞Εͳ͍ʂ ʯ • ↑ ࠓͰ͸࢖͍͜ͳͤΔΑ͏ʹͳΓ·ͨ͠ ※ ্ख͘ RelativeLayout Λ࢖͍͜ͳ͍ͤͯͳ͍ਤ 27
  17. ͦͷᶄ աڈͷաͪ • ΋͏͍͍େਓͳͷʹɺViewGroup ͷωετ͕ਂ͘ͳΔͱΞϓϦͷύ ϑΥʔϚϯε͕ѱ͘ͳΔ͜ͱΛ஌Βͣʹ LinearLayout ͱ FrameLayout Λ࢖͍·͘Δ

    • ʮݮΔ΋Μ͡Όແ͍͠ʯ • ʮ TextView Λάϧʔϐϯάͯ͠ margin, padding ·ͱΊͯઃఆ͠ Αʂʯ • ʮ ViewGroup Ͱ·ͱΊͯ ClickListener ઃఆͨ͠Ζʂ ʯ 28
  18. ͦͷᶅ աڈͷաͪ • RelativeLayout ΛҰ੾࢖ΘͣແࣄΞϓϦΛϦϦʔεʂ • ViewGroup ͷ֊૚͕ਂ͗ͯ͢ WebView ͷํ͕εΫϩʔϧ͕଎͍Ϩ

    ϕϧʂ • ޾͍ʹ΋(ʁ)ϨϏϡʔͰʮεΫϩʔϧ஗ա͗Δ΍Ζʂʯ
 ͱ͍͏ҙݟ͸ແ͔ͬͨ • ਓ͸஌Γಘͳ͍΋ͷΛٻΊͳ͍ͷ͔ 29
  19. ΞϓϦͷεΫϩʔϧ͕ ΊͪΌ×2 ஗͘ͳΔ ViewGroup ͷଟॏωετʹΑΔѱӨڹ • Android 5.0, 6.0ܥ͸εϖοΫ͕͍͍ͷͰ ViewGroup

    Λωετͤ͞ ͍ͯͯ΋ׂͱεϜʔζʹεΫϩʔϧ͢Δ • Android 4.0ܥͰ͸εΫϩʔϧ͕ॏ͗ͯ͢࢖͍෺ʹͳΒͳ͍Ϩϕϧ • ૣ͘αϙʔτΛ੾Γ͍ͨʂͱࢥ͏΄Ͳ 30