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 課程 - Part3: Android app 實作
Search
Johnny Sung
June 30, 2019
Programming
0
70
炎炎夏日學 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
Kubernetes 地端自建 v.s. GKE,哪個更適合你? @Devfest Taipei 2024
j796160836
0
10
地端自建 Kubernetes (K8s) 小宇宙 (On-premises Kubernetes) @ CNTUG 2024/11 Meetup #63
j796160836
0
11
[AI LLM] Gemma 初體驗 @ GDG Cloud Taipei Meetup #70
j796160836
0
11
ArgoCD 的雷 碰過的人就知道 @TSMC IT Community Meetup #4
j796160836
0
50
使用 Kong 與 GitOps 來管理您企業的 API 呼叫 @ 2024 台灣雲端大會
j796160836
0
46
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @ Devfest Taipei 2023
j796160836
0
140
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具
j796160836
0
20
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
j796160836
0
37
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
j796160836
0
230
Other Decks in Programming
See All in Programming
Multi Step Form, Decentralized Autonomous Organization
pumpkiinbell
1
650
Simple組み合わせ村から大都会Railsにやってきた俺は / Coming to Rails from the Simple
moznion
3
4.4k
Unity Android XR入門
sakutama_11
0
110
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
760
定理証明プラットフォーム lapisla.net
abap34
1
1.7k
『品質』という言葉が嫌いな理由
korimu
0
160
Amazon S3 TablesとAmazon S3 Metadataを触ってみた / 20250201-jawsug-tochigi-s3tables-s3metadata
kasacchiful
0
100
Djangoアプリケーション 運用のリアル 〜問題発生から可視化、最適化への道〜 #pyconshizu
kashewnuts
1
230
DROBEの生成AI活用事例 with AWS
ippey
0
130
Honoをフロントエンドで使う 3つのやり方
yusukebe
3
1.4k
WebDriver BiDiとは何なのか
yotahada3
1
130
ファインディの テックブログ爆誕までの軌跡
starfish719
2
1.1k
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
51
7.4k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
9
1.3k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
The Invisible Side of Design
smashingmag
299
50k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
The Cult of Friendly URLs
andyhume
78
6.2k
Fireside Chat
paigeccino
34
3.2k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
Music & Morning Musume
bryan
46
6.3k
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