in Kotlin starting from 2.5.0 Performance Improvements with KSP in 2.4.0 Room-Paging Support (Paging 3.0) Relational Query Methods androidx.room:room:2.4.2 https://developer.android.com/jetpack/androidx/releases/room#2.4.0
etc. // 1:1 Relation Map @Query("SELECT * FROM Song JOIN Artist ON Song.artistId = Artist.artistId") fun getSongAndArtist(): Map<Song, Artist> // 1:N Relation Map @Query("SELECT * FROM Artist JOIN Album ON Artist.id = Album.artistId") fun getArtistAndAlbums(): Map<Artist, List<Album>> https://developer.android.com/training/data-storage/room/accessing-data#multimap
to handling of invalid or stale data More comprehensive callbacks New introductory codelab for Paging 3 androidx.paging:paging:3.1.1 https://developer.android.com/jetpack/androidx/releases/paging#3.1.0
Multiple Back Stacks Support for two-pane layouts All artifacts rewritten in Kotlin androidx.navigation:navigation:2.4.2 https://developer.android.com/jetpack/androidx/releases/navigation#2.4.0
SharedPreferences to Proto DataStore. d.android.com/codelabs/android-proto-datastore#7 androidx.datastore:datastore:1.0.0 https://developer.android.com/jetpack/androidx/releases/datastore#1.0.0
issues using internal heuristics Provides UI context to attribute data to user states and actions Reports results on every frame via a listener androidx.metrics:metrics-performance:1.0.0-alpha01 https://developer.android.com/topic/performance/jankstats
libraries Startup and jank performance improvements Profiles added to popular Jetpack libraries androidx.profileinstaller:profileinstaller:1.1.0 https://developer.android.com/jetpack/androidx/releases/navigation#2.4.0
custom trace-based timing measurement with TraceSectionMetric Allow detection of audio underruns with AudioUnderrunMetric Added BaselineProfileRule to generate profiles for critical workflows androidx.benchmark:benchmark-macro:1.1.0 https://developer.android.com/topic/performance/benchmarking/macrobenchmark-overview
// called by the adapter when an item is selected. fun openDetails(itemId: Int) { childFragmentManager.commit { setReorderingAllowed(true) replace<ItemFragment>(R.id.detail_container, bundleOf("itemId" to itemId)) // If we're already open and the detail pane is visible, // crossfade between the fragments. if (binding.slidingPaneLayout.isOpen) { setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) } } binding.slidingPaneLayout.open() } https://developer.android.com/guide/topics/ui/layout/twopane
layout avoids placing content in occluded areas Already integrated into SlidingPaneLayout WindowManager Stable androidx.window:window:1.0.0 https://developer.android.com/jetpack/androidx/releases/window#1.0.0
and drop in response to // both long press and mouse drag events. Note the call to attach() at the end. Without it, // the listener would never actually be attached to the view. Also note that attach() replaces // any OnTouchListener or OnLongClickListener already attached to the view. DragStartHelper(binding.textDragItem) { view, _ -> val text = (view as TextView).text // Create the ClipData to be shared val dragClipData = ClipData.newPlainText(/*label*/"Text", text) // Use the default drag shadow val dragShadowBuilder = View.DragShadowBuilder(view) // Initiate the drag. Note the DRAG_FLAG_GLOBAL, which allows for drag events to be istened // to by apps other than the source app. view.startDragAndDrop(dragClipData, dragShadowBuilder, null, DRAG_FLAG_GLOBAL) }.attach() https://github.com/android/user-interface-samples/tree/main/DragAndDrop
ClipDescription.MIMETYPE_TEXT_PLAIN, "application/x-arc-uri-list" // Support external items on Chrome OS Android 9 ), DropHelper.Options.Builder() .setHighlightColor(getColor(R.color.purple_300)) .build() ) { view, payload -> resetDropTarget() val item = payload.clip.getItemAt(0) val (_, remaining) = payload.partition { it == item } if (payload.clip.description.hasMimeType(MIMETYPE_TEXT_PLAIN) { binding.textDropTarget.text = item.text } // Allow the system to handle any remaining ClipData.Item objects if applicable // remaining } https://github.com/android/user-interface-samples/tree/main/DragAndDrop
Set app locales val locales: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY") // or LocaleListCompat.create(Locale.KOREA) AppCompatDelegate.setApplicationLocales(locales) https://developer.android.com/about/versions/13/features/app-languages#androidx-impl
// Preferred locales are managed automatically on API level 33+, // but we need to load them manually on earlier platform versions. val locales = loadLocalesFromPreferences() AppCompatDelegate.setApplicationLocales(locales) } super.attachBaseContext(newBase) } <service android:name="androidx.appcompat.app.AppLocalesMetadataHolderService" android:enabled="false" android:exported="false"> <meta-data android:name="autoStoreLocales" android:value="true" /> </service> https://developer.android.com/about/versions/13/features/app-languages#androidx-impl
// Preferred locales are managed automatically on API level 33+, // but we need to load them manually on earlier platform versions. val locales = loadLocalesFromPreferences() AppCompatDelegate.setApplicationLocales(locales) } super.attachBaseContext(newBase) } <service android:name="androidx.appcompat.app.AppLocalesMetadataHolderService" android:enabled="false" android:exported="false"> <meta-data android:name="autoStoreLocales" android:value="true" /> </service> https://developer.android.com/about/versions/13/features/app-languages#androidx-impl
this framework. Compose has been instrumental in unlocking better velocity and smoother landings for the app.” 01 “Compose makes it much easier to define our own components and to make their API contracts more explicit, flexible, and intuitive.” 02 “Jetpack Compose is a critical part of our technical strategy. The productivity gains are massive.” 03 Jetpack Compose Google Play Twitter AirBnB