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
star_zero
December 07, 2019
Programming
380
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
490
Coroutines Test 入門 / Android Test Night #8
star_zero
2
1.3k
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
620
Other Decks in Programming
See All in Programming
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
140
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
390
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
220
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
300
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
Oxlintのカスタムルールの現況
syumai
6
1.2k
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
120
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
320
RTSPクライアントを自作してみた話
simotin13
0
630
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
160
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
620
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
170
Test your architecture with Archunit
thirion
1
2.3k
Automating Front-end Workflow
addyosmani
1370
210k
Prompt Engineering for Job Search
mfonobong
0
350
ラッコキーワード サービス紹介資料
rakko
1
3.7M
Navigating Team Friction
lara
192
16k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
170
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
620
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開発を高速に
ありがとうございました