Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Android Jetpack (再)入門 / DevFest Okayama 2019
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
star_zero
December 07, 2019
Programming
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Android Jetpack (再)入門 / DevFest Okayama 2019
star_zero
December 07, 2019
More Decks by star_zero
See All by star_zero
今からはじめるAndroidアプリ開発 2024 / DevFest 2024
star_zero
0
1.6k
Jetpack Compose の Side-effect を使いこなす / DroidKaigi 2023
star_zero
5
7.1k
Android 14 新機能 / Android 14 Meetup Nagoya
star_zero
1
680
Android 14 と Predictive back gesture / Shibuya.apk #42
star_zero
0
500
Coroutines Test 入門 / Android Test Night #8
star_zero
2
1.4k
What's new in Jetpack / I/O Extended Japan 2022
star_zero
1
710
Kotlin 2021 Recap / DevFest 2021
star_zero
3
1.4k
Kotlin Symbol Processing (KSP) を使ったコード生成 / DroidKaigi 2021
star_zero
2
5.3k
What's new Android 12
star_zero
0
630
Other Decks in Programming
See All in Programming
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
200
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
150
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
120
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
170
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
180
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
610
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
0
400
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.9k
AIが無かった頃の素敵な出会いの話
codmoninc
1
230
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
510
Featured
See All Featured
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
350
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
310
The Limits of Empathy - UXLibs8
cassininazir
1
550
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
45k
So, you think you're a good person
axbom
PRO
2
2.1k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
470
Automating Front-end Workflow
addyosmani
1370
210k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
270
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Transcript
Android Jetpack (再)入門 DevFest Okayama 2019 2019/12/07
About me • Kenji Abe • クックパッド株式会社 • Google Developers
Experts for Android • Twitter: @STAR_ZERO
話すこと • Android Jetpackの概要 • 各ライブラリの簡単な紹介と使い方 ‣ たくさんあるのでザックリと
Jetpack?
Jetpack? https://developer.android.com/jetpack
Jetpack? • Android開発を加速させてくれるライ ブラリやツールなど • プラットフォームのAPIからは独立さ れてる • 頻繁にアップデートされる •
必要なものだけを使用可能
Jetpack? https://developer.android.com/jetpack/androidx/versions
Architecture • https://developer.android.com/ jetpack/docs/guide • 推奨しているアーキテクチャのガイド • Jetpackを使うならこれに従うと良い • MVVM
+ Repsitory
Jetpack?
各ライブラリの 紹介
使ったほうが良い
使ったほうが良い • AppCompat • Lifecycles • ViewModel • LiveData
AppCompat • 古いOSとの下位互換 • マテリアルデザインのサポート • 新規プロジェクトでは自動で追加され る • 必ず使いましょう
AppCompat • AppCompatActivity, Fragment • AppCompatButton, AppCompatTextViewなど ‣ レイアウトのButton/TextViewなどは 自動で変換される
• その他色々
Lifecycles • Activity/Fragmentのライフサイクル の状態を管理 ‣ LifecycleOwnerを実装してる • ライフサイクルの状態を監視できる • LifecycleOwner使って連携
Lifecycles https://developer.android.com/topic/libraries/architecture/lifecycle
ViewModel • Viewのデータを保持する • 回転などでデータを失わない ‣ Viewなどを保持するとメモリリークす る ‣ OSが破棄したときは対応が必要
ViewModel https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel class MainViewModel : ViewModel() { // } class MainActivity
: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val viewModel = ViewModelProviders .of(this).get(MainViewModel::class.java) } }
LiveData • Observe可能なデータホルダー • Lifecycleのことを知ってる • LifecycleがSTARTED/RESUMEDのと きに変更を通知 • 他のライブラリでも多く使われてる
LiveData class MainViewModel : ViewModel() { private val _data =
MutableLiveData<String>() val data: LiveData<String> = _data fun fetchData() { val result = // データ取得 _data.value = result } }
LiveData class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ viewModel.data.observe(this, Observer { // LiveDataが変更されるとココに通知される }) } }
使っていきたい
使っていきたい • DataBinding • Navigation
DataBinding • レイアウト(XML)とデータを結合させる • データの変更を自動でUIへ反映 (LiveData) • イベント処理 • XMLに式が書ける
• XMLからコードを自動生成
DataBinding class MainViewModel : ViewModel() { private val _data =
MutableLiveData<String>() val data: LiveData<String> = _data fun fetchData() { val result = // データ取得 _data.value = result } }
DataBinding <layout> <data> <variable name="viewModel" type="com...MainViewModel" /> </data> <ConstraintLayout> <TextView
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{viewModel.data}" /> </ConstraintLayout> </layout>
DataBinding class MainActivity : AppCompatActivity() { private lateinit var binding:
ActivityMainBinding private val viewModel by lazy { } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil .setContentView(this, R.layout.activity_main) binding.lifecycleOwner = this binding.viewModel = viewModel } }
DataBinding fun onClickButton() { // ボタンが押されたときの処理 } <Button android:id="@+id/button" android:onClick="@{()
-> handler.onClickButton()}" />
Navigation • Navigation Editorで画面遷移を定義 ‣ XMLを直接編集も可能 • 主にFragment間の画面遷移 • 引数を型安全に受け渡し可能(SafeArgs)
• DeepLinkでの遷移
Navigation
Navigation
Navigation <ConstraintLayout> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>
Navigation fun onClickButton() { findNavController() .navigate(R.id.action_mainFragment_to_homeFragment) }
必要なときに
必要な時に • WorkManager • Room • Paging • CameraX
WorkManager • バックグラウンドタスクを実行 • ネットワークや充電状況を考慮 • OneTime、定期実行
WorkManager class MyWorker( context: Context, params: WorkerParameters ): Worker(context, params)
{ override fun doWork(): Result { // タスクを実行 return Result.success() } }
WorkManager val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true) .build() val workRequest
= OneTimeWorkRequestBuilder<MyWorker>() .setConstraints(constraints) .build() WorkManager.getInstance(context).enqueue(workRequest)
Room • SQLiteへ簡単にアクセス • @Database, @Entity, @Dao で構成 • リレーションのサポート
• Android StudioでのSQL構文チェック
Room @Entity data class User( @PrimaryKey val id: Int, @ColumnInfo(name
= "name") val name: String ) @Dao interface UserDao { @Query("SELECT * FROM user") fun getUsers(): List<User> @Insert fun insert(user: User) }
Room @Database(entities = [User::class], version = 1) abstract class AppDatabase:
RoomDatabase() { abstract fun userDao(): UserDao }
Room val db = Room.databaseBuilder( requireContext(), AppDatabase::class.java, "my-db" ).build() val
dao = db.userDao() // データ追加 dao.insert(User(1, "Kenji Abe")) // データ取得 val users = dao.getUsers()
Paging • RecyclerViewのオートページング • Roomは簡単に対応できる • ネットワークアクセスは自分で実装 • クセがあるので難しい
Paging @Dao interface UserDao { @Query("SELECT * FROM user ORDER
BY id") fun getUsersPaging(): DataSource.Factory<Int, User> } class UserViewMode : ViewModel() { val users = userDao.getUsersPaging().toLiveData(10) }
Paging class UsersAdapter : PagedListAdapter<User, ViewHolder>(DIFF_CALLBACK) { override fun onCreateViewHolder(/*
*/): ViewHolder { // ... return ViewHolder(view) } override fun onBindViewHolder((/* */) { holder.bind(getItem(position)) } }
Paging class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val adapter = UsersAdapter() recycler.layoutManager = LinearLayoutManager(this) recycler.adapter = adapter viewModel.users.observe(this, Observer { adapter.submitList(it) }) } }
CameraX • カメラアプリの開発を簡単に • デバイス依存コードが不要 • ベンダー拡張機能 ‣ HDR、Portraitなど
CameraX val previewConfig = PreviewConfig.Builder().apply { // ... }.build() val
preview = Preview(previewConfig) preview.setOnPreviewOutputUpdateListener { // ... } val imageCaptureConfig = ImageCaptureConfig.Builder() .apply { // ... }.build() val imageCapture = ImageCapture(imageCaptureConfig) CameraX.bindToLifecycle(this, preview, imageCapture)
その他いろいろ
その他いろいろ • Benchmark ‣ パフォーマンス測定 • Biometric ‣ 生体認証 •
ViewPager2 ‣ ViewPagerの新実装(RecyclerView) • Security ‣ 暗号化まわり
KTX
• Kotlinの拡張関数を使って、記述を簡 単に • Coroutinesもサポート • https://developer.android.com/ kotlin/ktx/extensions-list KTX
KTX dependencies { implementation "androidx.core:core-ktx:1.1.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.1.0" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0" implementation
"androidx.navigation:navigation-fragment-ktx:2.1.0" implementation "androidx.navigation:navigation-ui-ktx:2.1.0" }
KTX preference.edit() .putBoolean("flag", true) .putInt("value", 1) .apply() // ktxを使った場合 preference.edit
{ putBoolean("flag", true) putInt("value", 1) }
KTX viewModel.data.observe(this, Observer { // ... }) // ktxを使った場合 viewModel.data.observe(this)
{ // ... }
Jetpack Compose
Jetpack Compose • Google I/O 2019で発表 • 宣言的UI ‣ Flutter,
React, Vue.jsに似てる • Kotlinで書く • まだPreview版 • Android Studio 4.0で試せる
Jetpack Compose
Jetpackを使って Android開発を高速に
ありがとうございました