Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
炎炎夏日學 Android 課程 - Part3: Android app 實作
Search
Johnny Sung
June 30, 2019
Programming
0
69
炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作
(Kotlin EveryWhere 活動)
Johnny Sung
June 30, 2019
Tweet
Share
More Decks by Johnny Sung
See All by Johnny Sung
ArgoCD 的雷 碰過的人就知道 @TSMC IT Community Meetup #4
j796160836
0
34
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
j796160836
0
26
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @ Devfest Taipei 2023
j796160836
0
110
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具
j796160836
0
13
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
j796160836
0
24
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
j796160836
0
220
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
j796160836
3
15k
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
j796160836
1
1.2k
談談 Android constraint layout
j796160836
0
91
Other Decks in Programming
See All in Programming
Jakarta EE meets AI
ivargrimstad
0
1.1k
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
140
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
9
3.8k
Leverage LLMs in Java with LangChain4j and Quarkus
hollycummins
0
100
みんなでプロポーザルを書いてみた
yuriko1211
0
300
N.E.X.T LEVEL
pluu
2
200
CSC509 Lecture 13
javiergs
PRO
0
120
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
140
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
2.2k
React CompilerとFine Grained Reactivityと宣言的UIのこれから / The next chapter of declarative UI
ssssota
7
2.6k
「天気予報があなたに届けられるまで」 - NIFTY Tech Talk #22
niftycorp
PRO
0
130
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
6
2.2k
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
870
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Git: the NoSQL Database
bkeepers
PRO
427
64k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Optimizing for Happiness
mojombo
376
70k
Building an army of robots
kneath
302
43k
Practical Orchestrator
shlominoach
186
10k
Writing Fast Ruby
sferik
627
61k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
A designer walks into a library…
pauljervisheath
204
24k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Transcript
炎炎夏⽇日學 Android Johnny Sung Part3: Android app 實作
Mobile device developer Johnny Sung https://fb.com/j796160836 https://blog.jks.coffee/ https://www.slideshare.net/j796160836 https://github.com/j796160836
⼩小試⾝身⼿手
震動 。
震動 <uses-permission android:name="android.permission.VIBRATE" /> val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibrator.vibrate(10) AndroidManifest.xml
震動 vibrator.vibrate(longArrayOf(80, 150, 80, 150, 80, 150), -1) vibrator.cancel()
None
休息⼀一下 ☕
軟體設計 • 企劃 • UI/UX 介⾯面設計(美術) • 程式 • 測試
所需材料 • 畫⾯面線框稿 (Wireframe) • API 接⼝口⽂文件 • 美術圖片
成功畫⾯面 載入中畫⾯面 錯誤畫⾯面
成功畫⾯面 載入中畫⾯面 錯誤畫⾯面 夕陽⼩小幫⼿手
成功畫⾯面 載入中畫⾯面 錯誤畫⾯面 夕陽⼩小幫⼿手
所需⼯工具 • Method Draw 線上編輯圖片⼯工具 https://editor.method.ac/ • App Icon Generator
線上 App icon 產⽣生⼯工具 https://appicon.co/ • JSON Editor Online 線上 JSON 編輯⼯工具 https://jsoneditoronline.org/
None
None
https://sunrise-sunset.org/api
22.604098, 120.3001811 K Square 經度 (Latitude) 緯度 (Longitude) 地址:806⾼高雄市前鎮區復興四路路 20
號 座標
None
None
None
https://api.sunrise-sunset.org/json?lat=22.604098&lng=120.3001811&date=today&formatted=0 今⽇日 K Square 夕陽時間
None
None
夕陽⼩小幫⼿手 使⽤用套件 • Gson 解析 JSON 資料 • OkHttp 網路路函式庫
• jDeferred 架構函式庫
dependencies { // ... implementation 'org.immutables:gson:2.7.1' implementation 'com.squareup.okhttp3:okhttp:3.12.0' implementation "org.jdeferred.v2:jdeferred-core:2.0.0-beta1"
implementation "org.jdeferred.v2:jdeferred-android:2.0.0-beta1" // ... } 加入套件參參考
None
None
None
None
class SunsetResponse { var results: SunsetResult? = null var status:
String? = null } class SunsetResult { var sunset: String? = null }
單元測試原則 • Arrange – 準備,準備輸入資料與期待值 • Act – 執⾏行行,執⾏行行測試對象 •
Assert – 驗證,驗證結果 3A 原則
class ExampleUnitTest { @Test fun addition_isCorrect() { // Arrange val
expected = 4 // Act val actual = 2 + 2 // Assert assertEquals(expected, actual) } } Arrange 準備 Act 執⾏行行 Aessrt 驗證
object SunsetDateUtil { val dateFormater = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US) .apply {
timeZone = TimeZone.getTimeZone("UTC") } }
Arrange 準備 Act 執⾏行行 Aessrt 驗證 @Test fun testJSON() {
// Arrange val json = "{\"results\":{\"sunrise\":\"2019-06-28T21:17:03+00:00\",\"sunset\":\"2019-06-29T10:47:28+00:00\",\"solar_noon\": \"2019-06-29T04:02:16+00:00\",\"day_length\":48625,\"civil_twilight_begin\":\"2019-06-28T20:52:00+00:00\",\"civil_twilight_end\": \"2019-06-29T11:12:31+00:00\",\"nautical_twilight_begin\":\"2019-06-28T20:22:00+00:00\",\"nautical_twilight_end\": \"2019-06-29T11:42:31+00:00\",\"astronomical_twilight_begin\":\"2019-06-28T19:50:46+00:00\",\"astronomical_twilight_end\": \"2019-06-29T12:13:46+00:00\"},\"status\":\"OK\"}" val excepted = "2019-06-29T10:47:28+00:00" // Act val gson = Gson() val obj = gson.fromJson(json, SunsetResponse::class.java) // Assert Assert.assertEquals(excepted, obj.results?.sunset) } }
Arrange 準備 Act 執⾏行行 Aessrt 驗證 輸入的資料 期待成功的資料 class SunsetUnitTest
{ @Test fun testFormatter() { val sunsetTime = "2019-06-24T10:46:49+00:00" val expected = Date(1561373209000) val result = SunsetDateUtil.dateFormater.parse(sunsetTime) assertEquals(expected.time, result.time) } }
class NetworkManager { companion object { val instance: NetworkManager by
lazy { NetworkManager() } } val mainHandler = Handler(Looper.getMainLooper()) inline fun <reified T> requestAsync(request: Request, typeToken: Type): Promise<T, Exception, Double> { val okHttpClient = OkHttpClient() val gson = GsonBuilder().create() val deferred = DeferredObject<T, Exception, Double>() okHttpClient.newCall(request).promise().then { okhttpResponse -> val strResult = okhttpResponse.body()?.string() try { val result = gson.fromJson<T>(strResult, typeToken) if (okhttpResponse.isSuccessful) { mainHandler.post { deferred.resolve(result) } } else { mainHandler.post { deferred.reject(Exception(strResult)) } } } catch (e: Exception) { mainHandler.post { deferred.reject(e) } } }.fail { deferred.reject(it) } return deferred.promise() } } fun Call.promise(): Promise<Response, Exception, Double> { val deferred = DeferredObject<Response, Exception, Double>() this.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { deferred.resolve(response) } override fun onFailure(call: Call, e: IOException) { deferred.reject(e) } }) return deferred.promise() } 補檔案 NetworkManager.kt
https://github.com/jdeferred/jdeferred
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
object NetworkAPI { fun getSunsetDataAsync(): Promise<SunsetResponse, Exception, Double> { val
okhttpRequest = Request.Builder() .url("https://api.sunrise-sunset.org/json?lat=22.604098&lng=120.3001811&date=today&formatted=0") .method("GET", null) .build() val type = object : TypeToken<SunsetResponse>() {}.type return NetworkManager.instance.requestAsync(okhttpRequest, type) } }
https://square.github.io/okhttp/
None
完成了了!
Q & A
趕快去追夕陽吧
None