Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's New in Android - I/O Extended Yangon 2018

What's New in Android - I/O Extended Yangon 2018

Talk from I/O Extended Yangon 2018.

0991ca4bc363163337f7b02b98af538a?s=128

Aung Kyaw Paing

July 08, 2018
Tweet

More Decks by Aung Kyaw Paing

Other Decks in Technology

Transcript

  1. What’s new in Android? Photo Ⓒ Rami Al-zayat

  2. What’s new in Android P? Photo Ⓒ Lauren Robert

  3. Notch Support Photo Ⓒ Google

  4. Notch Support - DisplayCount class - getDisplayCutout() method - New

    window attribute, layoutInDisplayCutoutMode - LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT - LAYOUT_IN_DISPLAY_CUTOUT_SHORT EDGES - LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
  5. LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT - The notch has to be contained in System

    Bar - If not, the window won’t overlap it
  6. LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES - Can extends into notch - Developer has to

    handle drawing
  7. LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER - Will never overlaps

  8. Notch Support if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val windowAttributes =

    window.attributes windowAttributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT }
  9. Notification - Person API - Can now display Image -

    Reply drafts - Group conversations support - Semantic Action (Reply, Mark as read, thumbs up… etc.) - Smart Reply Photo Ⓒ Google
  10. Notification // create new Person val sender = Person() .setName(name)

    .setUri(uri) .setIcon(null) .build() // create image message val message = Message("Picture", time, sender) .setData("image/";, imageUri) val style = Notification.MessagingStyle(getUser()) .addMessage("Check this out!", 0, sender) .addMessage(message)
  11. Notification Channel - Can block entire “groups” of channel -

    Can check if blocked via isBlocked - New policies
  12. TextView Photo Ⓒ Best practices for text on Android (

    Google IO / 18 )
  13. Photo Ⓒ Best practices for text on Android ( Google

    IO / 18 )
  14. PreComputed Text // UI thread val params: PrecomputedText.Params = textView.getTextMetricsParams()

    val ref = WeakReference(textView) executor.execute { // background thread val text = PrecomputedText.create("Hello", params) val textView = ref.get() textView?.post { // UI thread val textViewRef = ref.get() textViewRef?.text = text } }
  15. Magnifier

  16. Magnifier fun onTouchEvent(event: MotionEvent): Boolean { when (event.actionMasked) { MotionEvent.ACTION_DOWN

    -> magnifier.show(event.x, event.y) MotionEvent.ACTION_MOVE -> magnifier.show(event.x, event.y) MotionEvent.ACTION_UP -> magnifier.dismiss() } }
  17. Smart Linkify

  18. Smart Linkify // UI thread val text: Spannable = ...

    val request = TextLinks.Request.Builder(text) val ref = WeakReference(textView) executor.execute { // background thread TextClassifier.generateLinks(request).apply(text) val textView = ref.get() textView?.post { // UI thread val textViewRef = ref.get() textViewRef?.text = text } }
  19. Fingerprint Auth

  20. And…. - Indoor positioning - Multi-camera support - ImageDecoder -

    AnimatedImageDrawable - Client side encryptions for backups - New accessibility features - Autofill improvements - And Many more!
  21. What’s new in Android Support Library? Photo Ⓒ Leo Fosdal

  22. Major Refactor android.support.v4.* android.support.v7.* android.support.v9.* android.support.v14.* …

  23. Major Refactor android.support.* androidx.*

  24. Major Refactor Available in Android Studio Canary Channel

  25. Major Refactor https://developer.android.com/topic/libraries/support-library/refactor

  26. Android KTX https://github.com/android/android-ktx

  27. Android KTX sharedPreferences.edit { putBoolean("key", value) putLong("key2", value2) } val

    args = bundleOf { "key" to 1, "key2" to true }
  28. Android JetPack https://developer.android.com/jetpack/

  29. Slices - UI templates with interactive contents - Used in

    Google Search, Google Assistant
  30. Slices fun createSliceWithGridRow(sliceUri: Uri): Slice { // Create the parent

    builder. return list(context, sliceUri, ListBuilder.INFINITY) { header { setTitle("Famous restaurants") setPrimaryAction(SliceAction(pendingIntent, icon, "Famous restaurants")) } gridRow { cell { addImage(image1, LARGE_IMAGE) addTitleText("Top Restaurant") addText("0.3 mil") setContentIntent(intent1) } cell { addImage(image2, LARGE_IMAGE) addTitleText("Fast and Casual") addText("0.5 mil") setContentIntent(intent2) } } } }
  31. Actions - Can recommend actions to users - Increases discoverability

  32. RecyclerView ListAdapter - Uses DiffUtils - Automatic Animation

  33. class MovieRecyclerViewAdapter : ListAdapter<Movie, MovieViewHolder>() { } RecyclerView ListAdapter

  34. RecyclerView ListAdapter companion object { private val MOVIE_DIFF_CALLBACK = object

    : DiffUtil.ItemCallback<Movie>() { override fun areItemsTheSame(item1: Movie, item2: Movie): Boolean { return item1.id == item2.id } override fun areContentsTheSame(item1: Movie, item2: Movie): Boolean { return item1 == item2 } } }
  35. class MovieRecyclerViewAdapter : ListAdapter<Movie, MovieViewHolder>(MOVIE_DIFF_CALLBACK) { companion object { private

    val MOVIE_DIFF_CALLBACK = object : DiffUtil.ItemCallback<Movie>() { override fun areItemsTheSame(item1: Movie, item2: Movie): Boolean { return item1.id == item2.id } override fun areContentsTheSame(item1: Movie, item2: Movie): Boolean { return item1 == item2 } } } } RecyclerView ListAdapter
  36. movieListLiveData.observe(this, Observer {itemList -> movieRecyclerViewAdapter.submitList(itemList) }) RecyclerView ListAdapter

  37. RecyclerView Selection - Allow select/deselect multiple items in list SelectionTracker

    tracker = new SelectionTracker.Builder<>( "my-selection-id", recyclerView, new StableIdKeyProvider(recyclerView), new MyDetailsLookup(recyclerView), StorageStrategy.createLongStorage()) .build();
  38. Material Components https://material.io/

  39. BottomAppBar

  40. BottomAppBar <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Other components and

    views --> <com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:navigationIcon="@drawable/ic_menu_24"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_anchor="@id/bar"/> </android.support.design.widget.CoordinatorLayout>
  41. MaterialButton

  42. MaterialButton <com.google.android.material.button.MaterialButton android:id="@+id/material_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_label_enabled"/>

  43. MaterialCardView

  44. MaterialCardView <com.google.android.material.card.MaterialCardView style="@style/Widget.MaterialComponents.CardView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/mtrl_card_spacing" android:layout_marginTop="@dimen/mtrl_card_spacing" android:layout_marginRight="@dimen/mtrl_card_spacing" android:minHeight="200dp"> <!--

    Card contents. --> </com.google.android.material.card.MaterialCardView>
  45. Chips

  46. Chips <com.google.android.material.chip.Chip android:layout_width="wrap_content" android:layout_height="wrap_content" app:chipText="@string/hello_world"/> style="@style/Widget.MaterialComponents.Chip.Entry" style="@style/Widget.MaterialComponents.Chip.Filter" style="@style/Widget.MaterialComponents.Chip.Choice"

  47. Chips <com.google.android.material.chip.ChipGroup android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- Chips can be declared here,

    or added dynamically. --> </com.google.android.material.chip.ChipGroup>
  48. Android Arch Components - Paging Library - WorkManager - Navigation

  49. - Use for enqueuing background works - JobScheduler for API

    23+ - Firebase JobDispatcher (or) custom AlarmManager + Broadcast Receiver for backport WorkManager
  50. val workManager = WorkManager.getInstance() val workRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java).build() workManager.enqueue(workRequest) WorkManager

  51. val workManager = WorkManager.getInstance() val workConstraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.METERED) .setRequiresCharging(true)

    .setRequiresStorageNotLow(false) .build() val workRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java) .setConstraints(workConstraints) .build() workManager.enqueue(workRequest) WorkManager
  52. val workManager = WorkManager.getInstance() val workRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java).build() workManager.enqueue(workRequest) WorkManager

  53. val workManager = WorkManager.getInstance() val workRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java).build() workManager.enqueue(workRequest) val

    workStatusLiveData = workManager.getStatusById(workRequest.id) workStatusLiveData.observe(this, Observer { workStatus -> when (workStatus?.state) { State.ENQUEUED -> TODO() State.RUNNING -> TODO() State.SUCCEEDED -> TODO() State.FAILED -> TODO() State.BLOCKED -> TODO() State.CANCELLED -> TODO() } }) WorkManager
  54. val workManager = WorkManager.getInstance() val workRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java).build() workManager.enqueue(workRequest) workManager.cancelWorkById(workRequest.id)

    WorkManager
  55. WorkManager val workManager = WorkManager.getInstance() val request1 = OneTimeWorkRequest.Builder(FooWorker::class.java).build() val

    request2 = OneTimeWorkRequest.Builder(BarWorker::class.java).build() val request3 = OneTimeWorkRequest.Builder(BazWorker::class.java).build() workManager.beginWith(request1, request2).then(request3).enqueue()
  56. Navigation Arch Component - Single Activity, Multiple Fragment - Uses

    “Stack”, last-in first out structure - Deep Link has same stack
  57. Navigation Arch Component

  58. Navigation Arch Component <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"

    app:startDestination=“@id/blankFragment"> <fragment android:id="@+id/blankFragment" android:name="com.example.cashdog.cashdog.BlankFragment" android:label="fragment_blank" tools:layout="@layout/fragment_blank" /> <fragment android:id="@+id/blankFragment2" android:name="com.example.cashdog.cashdog.BlankFragment2" android:label="Blank2" tools:layout="@layout/fragment_blank_fragment2" /> </navigation>
  59. Navigation Arch Component <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"

    app:startDestination=“@id/blankFragment"> <fragment android:id="@+id/blankFragment" android:name="com.example.cashdog.cashdog.BlankFragment" android:label="fragment_blank" tools:layout="@layout/fragment_blank" > <action android:id="@+id/action_blankFragment_to_blankFragment2" app:destination="@id/blankFragment2" /> </fragment> <fragment android:id="@+id/blankFragment2" android:name="com.example.cashdog.cashdog.BlankFragment2" android:label="fragment_blank_fragment2" tools:layout="@layout/fragment_blank_fragment2" /> </navigation>
  60. Navigation Arch Component ?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/nav_graph" app:defaultNavHost="true" /> </android.support.constraint.ConstraintLayout>
  61. Navigation Arch Component override fun onSupportNavigateUp() = findNavController(R.id.nav_host_fragment).navigateUp()

  62. Navigation Arch Component button.setOnClickListener( Navigation.createNavigateOnClickListener(R.id.next_fragment, null) )

  63. <fragment android:id="@+id/details_page_fragment" android:label="@string/details" android:name="com.example.android.myapp.DetailsFragment" /> Navigation Arch Component - NavigationView(Drawer)

  64. <fragment android:id="@+id/details_page_fragment" android:label="@string/details" android:name="com.example.android.myapp.DetailsFragment" /> <item android:id="@id/details_page_fragment" android:icon="@drawable/ic_details" android:title="@string/details" />

    Navigation Arch Component - NavigationView(Drawer)
  65. <fragment android:id="@+id/details_page_fragment" android:label="@string/details" android:name="com.example.android.myapp.DetailsFragment" /> <item android:id="@id/details_page_fragment" android:icon="@drawable/ic_details" android:title="@string/details" />

    val navController = Navigation.findNavController(this, R.id.nav_host_fragment) val navigationView = findViewById<NavigationView>(R.id.nav_view) navigationView.setupWithNavController(navController) Navigation Arch Component - NavigationView(Drawer)
  66. Navigation Arch Component - Arguments <fragment android:id="@+id/confirmationFragment" android:name="com.example.cashdog.cashdog.ConfirmationFragment" android:label="fragment_confirmation" tools:layout="@layout/fragment_confirmation">

    <argument android:name="amount" android:defaultValue=”0” />
  67. Navigation Arch Component - Arguments <fragment android:id="@+id/confirmationFragment" android:name="com.example.cashdog.cashdog.ConfirmationFragment" android:label="fragment_confirmation" tools:layout="@layout/fragment_confirmation">

    <argument android:name="amount" android:defaultValue=”0” /> var bundle = bundleOf("amount" to amount) view.findNavController().navigate(R.id.confirmationAction, bundle)
  68. Navigation Arch Component - Arguments <fragment android:id="@+id/confirmationFragment" android:name="com.example.cashdog.cashdog.ConfirmationFragment" android:label="fragment_confirmation" tools:layout="@layout/fragment_confirmation">

    <argument android:name="amount" android:defaultValue=”0” /> var bundle = bundleOf("amount" to amount) view.findNavController().navigate(R.id.confirmationAction, bundle) val tv = view.findViewById(R.id.textViewAmount) tv.text = arguments.getString("amount")
  69. Navigation Arch Component - Safe Args apply plugin: 'com.android.application' apply

    plugin: 'androidx.navigation.safeargs' android { //... }
  70. Navigation Arch Component - Safe Args <fragment android:id="@+id/confirmationFragment" android:name="com.example.buybuddy.buybuddy.ConfirmationFragment" android:label="fragment_confirmation"

    tools:layout="@layout/fragment_confirmation"> <argument android:name="amount" android:defaultValue="1" app:type="integer"/> </fragment>
  71. Navigation Arch Component - Safe Args <fragment android:id="@+id/specifyAmountFragment" android:name="com.example.buybuddy.buybuddy.SpecifyAmountFragment" android:label="fragment_specify_amount"

    tools:layout="@layout/fragment_blank" > <action android:id="@+id/action_specify_to_confirm" app:destination="@id/confirmationFragment" /> </fragment> <fragment android:id="@+id/confirmationFragment" android:name="com.example.buybuddy.buybuddy.ConfirmationFragment" android:label="fragment_confirmation" tools:layout="@layout/fragment_confirmation"> <argument android:name="amount" android:defaultValue="1" app:type="integer"/ > </fragment>
  72. Navigation Arch Component - Safe Args override fun onClick(v: View?)

    { val amount = 100 val action = SpecifyAmountFragmentDirections.confirmationAction(amount) v.findNavController().navigate(action) }
  73. Navigation Arch Component - Safe Args override fun onClick(v: View?)

    { val amount = 100 val action = SpecifyAmountFragmentDirections.confirmationAction(amount) v.findNavController().navigate(action) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tv: TextView = view.findViewById(R.id.textViewAmount) val amount = ConfirmationFragmentArgs.fromBundle(arguments).amount tv.text = amount.toString() }
  74. https://github.com/googlesamples/android-sunflower

  75. ConstraintLayout 1.1 - Barrier - Group - Circular constraints -

    Chains - Constraint set
  76. ConstraintLayout 2.0 - ConstraintProperties - MotionLayout - Better Optimizers

  77. - Kotlin Support - New APIs Testing

  78. - Kotlin Support - New APIs assertEquals(view.visibility, View.VISIBLE) Testing

  79. - Kotlin Support - New APIs assertEquals(view.visibility, View.VISIBLE) “Failed Expected

    0 but was 16” Testing
  80. - Kotlin Support - New APIs assertEquals(view.visibility, View.VISIBLE) Testing

  81. - Kotlin Support - New APIs assertThat(view).isVisible() Testing

  82. - Kotlin Support - New APIs assertThat(view).isVisible() “Failed, view was

    not visible” Testing
  83. Testing - Roboelectric to be packaged inside androidx.test - Roboelectric

    semantics will be same as Espresso http://robolectric.org/blog/2018/05/09/robolectric-4-0-alpha/
  84. Testing - Roboelectric to be packaged inside androidx.test - Roboelectric

    semantics will be same as Espresso - Will be able to run UI test in local JVM http://robolectric.org/blog/2018/05/09/robolectric-4-0-alpha/
  85. Project Nitrogen

  86. What’s new in Android Development Tools? Photo Ⓒ Fleur Treurniet

  87. App Bundle - A new publishing format, instead of APK

    - Minimized APK depends on user’s device - Deliver downloadable “dynamic feature”
  88. D8 - New dex-ing tool - Default already on Android

    Studio 3.1 - Manually turn on by adding android.enableD8=true in gradle.properties
  89. R8 - Better Proguard - Can include proguard rules in

    java library module by placing inside “META-INF/proguard”
  90. Emulator - Saving states (Cold boot / Hot boot) -

    AMD CPU support - Notch emulation - Sceneform emulation
  91. Android Studio Canary - Navigation Arch Component Support - MotionLayout

    Support - Better Profiler - WebP support
  92. Android Studio on ChromeOS

  93. Play Store - Digital Rights Management(DRM) metadata - App now

    have to be complaint with GDPR - Algorithm changes - Must have minimum API level 26 by end of August 2018
  94. Q & A