$30 off During Our Annual Pro Sale. View Details »

Dailymotion En Apparté

Dailymotion En Apparté

An introduction to the Android Tech at dailymotion. All you ever wanted to know about the Dailymotion Android app with a focus on 2 things that set the app appart: automation & storage. Sorry, in french only.

mbonnin

March 28, 2019
Tweet

More Decks by mbonnin

Other Decks in Programming

Transcript

  1. Dailymotion Android App March 28th, 2019

  2. Plan 2 2 1. Historique de l'app. 2. Stack tech.

    3. Focus: automatisation de nos processus. 4. Focus: SQL delight.
  3. The home for videos that matter 3 milliards video vues

    par mois 300 millions visiteurs uniques par mois 150 millions vidéos dans le catalogue CHIFFRES CLES 3
  4. © 2018 CONFIDENTIAL RETROFIT 8 années d'app Android FIRST RELEASE

    MATERIAL DESIGN 2012 2019 2016 2015 2018 2017 2014 2013 NEON NEXT 2x 3x 4x MEDIAPLAYER EXOPLAYER WEBVIEW PLAYER GRAPHQL VOLLEY JACKSON GSON ANDROIDX MOSHI ROOM SQL DELIGHT KOTLIN PAPERDB RXJAVA COROUTINES BUTTERKNIFE SYNTHETIC PROPERTIES DAGGER SINGLE ACTIVITY ORMLITE JAVA
  5. © 2018 CONFIDENTIAL Stack technique 5

  6. Présentation Dailymotion Android en quelques mots... Single Activity Aucun fragment

    Kotlin à 75% Coroutines depuis 4 mois ≈ 58k lignes de code Android App Bundle 6 STACK TECH 6 SavedInstanceState
  7. © 2018 CONFIDENTIAL STACK TECH Architecture 7 MVP Dagger Epoxy

    L’incontournable Introduction en Septembre 2018 Déploiement progressif Librairie d’AirBnb Gestion de RecyclerView Support du diff
  8. © 2018 CONFIDENTIAL Mobile & tablette TV Modules STACK TECH

    8 Partner
  9. © 2018 CONFIDENTIAL Modules STACK TECH 9 Mobile Tablette Partner

    TV Shared Tracking Design
  10. © 2018 CONFIDENTIAL Outils STACK TECH 10 •Saucelabs •HockeyApps •Braze

    •Firebase •Transifex •Bitrise •Jira •Slack Intégration continue GitHub User Test
  11. © 2018 CONFIDENTIAL Interlude (Questions ?) 11

  12. © 2018 CONFIDENTIAL Focus technique : Kinta 12

  13. © 2018 CONFIDENTIAL FOCUS TECH KINTA 13 • Librairie Kotlin

    • Script nos workflows • Interface les outils • L’utilitaire du dev • Process d’une release Kinta : le couteau suisse • Intelligence des builds • Sauvegarde des artefacts
  14. © 2018 CONFIDENTIAL Process d’une release FOCUS TECH KINTA 14

    Release Beta Pre-launch Report Release Prod rollout
  15. © 2018 CONFIDENTIAL Track.BETA -> { val aabFile= getAabFile(versionCode, module)

    //Upload aab on beta track publisherHelper.uploadBetaBundle(aabFile, prodVersionCode,lastReleaseName) //Upload WhatsNew data for this versionCode WhatsNew(publisherHelper).run(listOf(versionCode, transifex_key)) //Send slack info Slack.sendNotif("androiddev", "Version $versionCode is in beta stage") } $ kinta beta 13712 dailymotion transifex_key
  16. © 2018 CONFIDENTIAL Track.BETA -> { val aabFile= getAabFile(versionCode, module)

    //Upload aab on beta track publisherHelper.uploadBetaBundle(aabFile, prodVersionCode,lastReleaseName) //Upload WhatsNew data for this versionCode WhatsNew(publisherHelper).run(listOf(versionCode, transifex_key)) //Send slack info Slack.sendNotif("androiddev", "Version $versionCode is in beta stage") } $ kinta beta 13712 dailymotion transifex_key
  17. © 2018 CONFIDENTIAL Track.BETA -> { val aabFile= getAabFile(versionCode, module)

    //Upload aab on beta track publisherHelper.uploadBetaBundle(aabFile, prodVersionCode,lastReleaseName) //Upload WhatsNew data for this versionCode WhatsNew(publisherHelper).run(listOf(versionCode, transifex_key)) //Send slack info Slack.sendNotif("androiddev", "Version $versionCode is in beta stage") } $ kinta beta 13712 dailymotion transifex_key
  18. © 2018 CONFIDENTIAL Track.BETA -> { val aabFile= getAabFile(versionCode, module)

    //Upload aab on beta track publisherHelper.uploadBetaBundle(aabFile, prodVersionCode,lastReleaseName) //Upload WhatsNew data for this versionCode WhatsNew(publisherHelper).run(listOf(versionCode, transifex_key)) //Send slack info Slack.sendNotif("androiddev", "Version $versionCode is in beta stage") } $ kinta beta 13712 dailymotion transifex_key
  19. © 2018 CONFIDENTIAL Track.BETA -> { val aabFile= getAabFile(versionCode, module)

    //Upload aab on beta track publisherHelper.uploadBetaBundle(aabFile, prodVersionCode,lastReleaseName) //Upload WhatsNew data for this versionCode WhatsNew(publisherHelper).run(listOf(versionCode, transifex_key)) //Send slack info Slack.sendNotif("androiddev", "Version $versionCode is in beta stage") } $ kinta beta 13712 dailymotion transifex_key
  20. © 2018 CONFIDENTIAL Track.RELEASE -> { //Deploy version or update

    the rollout publisherHelper.deployVersion(versionCode, userFraction) //Get all JIRA tickets and comment Changelog.getChangelog(versionCode, module).forEach { jiraUrl -> Jira.postComment(jiraUrl, "$versionCode is rolled out $userFraction %") } //Send slack info Slack.sendNotif("android_team", "$versionCode is rolled out $userFraction %") } $ kinta release 13712 dailymotion 5
  21. © 2018 CONFIDENTIAL Track.RELEASE -> { //Deploy version or update

    the rollout publisherHelper.deployVersion(versionCode, userFraction) //Get all JIRA tickets and comment Changelog.getChangelog(versionCode, module).forEach { jiraUrl -> Jira.postComment(jiraUrl, "$versionCode is rolled out $userFraction %") } //Send slack info Slack.sendNotif("android_team", "$versionCode is rolled out $userFraction %") } $ kinta release 13712 dailymotion 5
  22. © 2018 CONFIDENTIAL Track.RELEASE -> { //Deploy version or update

    the rollout publisherHelper.deployVersion(versionCode, userFraction) //Get all JIRA tickets and comment Changelog.getChangelog(versionCode, module).forEach { jiraUrl -> Jira.postComment(jiraUrl, "$versionCode is rolled out $userFraction %") } //Send slack info Slack.sendNotif("android_team", "$versionCode is rolled out $userFraction %") } $ kinta release 13712 dailymotion 5
  23. © 2018 CONFIDENTIAL Track.RELEASE -> { //Deploy version or update

    the rollout publisherHelper.deployVersion(versionCode, userFraction) //Get all JIRA tickets and comment Changelog.getChangelog(versionCode, module).forEach { jiraUrl -> Jira.postComment(jiraUrl, "$versionCode is rolled out $userFraction %") } //Send slack info Slack.sendNotif("android_team", "$versionCode is rolled out $userFraction %") } $ kinta release 13712 dailymotion 5
  24. © 2018 CONFIDENTIAL Focus technique : SQL Delight 24

  25. © 2018 CONFIDENTIAL SQL delight FOCUS TECH 25 1. Librairie

    square 2. Génération automatique de code Kotlin depuis du SQL. 3. Version 1.0 annoncée le 8 janvier https://github.com/square/sqldelight
  26. © 2018 CONFIDENTIAL -- build.gradle buildscript { ext.kotlin_version = Versions.kotlin

    repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' classpath "com.squareup.sqldelight:gradle-plugin:${Versions.sqldelight}" } } dependencies { implementation " com.squareup.sqldelight:android-driver:1.1.1" } apply plugin: "com.squareup.sqldelight" Configuration
  27. © 2018 CONFIDENTIAL -- src/main/sql/com/…/OfflineVideo.sq CREATE TABLE offlineVideo ( xid

    TEXT NOT NULL, title TEXT NOT NULL, duration REAL, [..more..] ); selectAll: SELECT * FROM offlineVideo; selectAllMatchingState: SELECT * FROM offlineVideo WHERE state = ?; insertVideo: INSERT OR REPLACE INTO offlineVideo VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); delete: DELETE FROM offlineVideo WHERE xid = ?; -- build/generated/…/OfflineVideo.kt interface OfflineVideo { val xid: String val title: String val duration: Double? … data class Impl(…) } -- build/generated/…/OfflineVideoQueries.kt class OfflineVideoQueries(private val database: Database, private val driver: SqlDriver) : Transacter(driver) { fun selectAll(): Query<OfflineVideo> fun selectAllMatchingState(state: SyncState?): Query<OfflineVideo> fun delete(xid: String) }
  28. © 2018 CONFIDENTIAL val driver = AndroidSqliteDriver(Database.Schema, applicationContext, »videos.db") val

    database = Database( driver = driver, offlineVideoAdapter = OfflineVideo.Adapter() ) val query = database.offlineVideoQueries.selectAll() val offlineVideoList:List<OfflineVideo> = query.executeAsList() Utilisation
  29. © 2018 CONFIDENTIAL @Entity data class User( @PrimaryKey var uid:

    Int, @ColumnInfo(name = "first_name") var firstName: String?, @ColumnInfo(name = "last_name") var lastName: String?, @ColumnInfo(name = "email") var lastName: String? ) val MIGRATION_2_3 = object : Migration(2, 3) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE Book ADD COLUMN email TEXT") } } Migrations Room
  30. © 2018 CONFIDENTIAL -- src/main/sql/com/…/1.sqm ALTER TABLE offlineVideo ADD COLUMN

    partner INTEGER NOT NULL; -- src/main/sql/com/…/OfflineVideo.sq CREATE TABLE offlineVideo ( [..more..] partner INTEGER NOT NULL, ); -- build/generated/…/OfflineVideo.kt interface OfflineVideo { val xid: String val title: String val duration: Double? val partner: Integer … data class Impl(…) } Migrations SQL Delight
  31. © 2018 CONFIDENTIAL -- build.gradle buildscript { ext.kotlin_version = Versions.kotlin

    repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' classpath "com.squareup.sqldelight:gradle-plugin:${Versions.sqldelight}" } } dependencies { implementation "com.squareup.sqldelight:ios-driver:1.1.1" } -- File.kt val driver = NativeSqliteDriver(Database.Schema,"videos.db") Multiplateforme
  32. © 2018 CONFIDENTIAL SQL delight FOCUS TECH 32 • Un

    seul schema • Vérification du SQL à la compilation • Plugin Android Studio • Coloration syntaxique • Autocomplete • Multiplateforme
  33. © 2018 CONFIDENTIAL La suite… • Modularisation • Coroutines •

    Plus de tests automatiques • Multiplatform ? • … • Design System!
  34. © 2018 CONFIDENTIAL Questions ? 34

  35. © 2018 CONFIDENTIAL Annexes FOCUS TECH 35 • https://www.meetup.com/fr-FR/Android- Paris/events/256368406/