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

New in Android @Google IO 18

New in Android @Google IO 18

Google announced some of the amazing features of Android P for users. Google doesn't fail to amaze android developers too. Here is the compiled version of what all was announced @ Google IO 18

Deesha Vora

May 26, 2018
Tweet

More Decks by Deesha Vora

Other Decks in Programming

Transcript

  1. Quick overview - JETPACK - ANDROIDX - DISTRIBUTION - App

    Bundle - ENGAGEMENT - Slices - ANDROID P
  2. ARCHITECTURE - NAVIGATION (alpha) Principles of Navigation • The app

    should have a fixed starting destination • A stack is used to represent the "navigation state" of an app • Up and Back are equivalent within your app's task • Deep linking to a destination or navigating to the same destination should yield the same stack
  3. ….. ARCHITECTURE - NAVIGATION (alpha) dependencies { def nav_version =

    "1.0.0-alpha01" implementation "android.arch.navigation:navigation-fragment:$nav_vers ion" // use -ktx for Kotlin implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin androidTestImplementation "android.arch.navigation:navigation-testing:$nav_versi on" // use -ktx for Kotlin }
  4. ….. ARCHITECTURE - NAVIGATION (alpha) <?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/androi d" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.cashdog.cashdog.MainFragment " android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_mainFragment_to_chooseRecipient" app:destination="@id/sendMoneyGraph" /> </fragment> <fragment android:id="@+id/viewBalanceFragment" android:name="com.example.cashdog.cashdog.ViewBalance Fragment" android:label="fragment_view_balance" tools:layout="@layout/fragment_view_balance" /> <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient"> <fragment android:id="@+id/chooseRecipient" android:name="com.example.cashdog.cashdog.ChooseRecip ient" android:label="fragment_choose_recipient" tools:layout="@layout/fragment_choose_recipient"> <action android:id="@+id/action_chooseRecipient_to_chooseAmount Fragment" app:destination="@id/chooseAmountFragment" /> </fragment> </navigation> </navigation>
  5. ARCHITECTURE - PAGING (1.0.0 Stable) dependencies { def paging_version =

    "1.0.0" implementation "android.arch.paging:runtime:$paging_version" // alternatively - without Android dependencies for testing testImplementation "android.arch.paging:common:$paging_version" // optional - RxJava support, currently in release candidate implementation "android.arch.paging:rxjava2:1.0.0-rc1" } UI components and considerations Data components and considerations
  6. …..ARCHITECTURE - PAGING - DATA Component 1. Construct an observable

    list 2. Define your own paging configuration 3. Choose the correct data source type Or Build your own data sources 4. Consider how content updates work 5. Provide mapping between data representations
  7. …..ARCHITECTURE - PAGING - DATA Component Construct an observable list

    A DataSource object loads pages for a single PagedList. The factory class creates new instances of PagedList in response to content updates, such as database table invalidations and network refreshes. interface ConcertDao { // The Integer type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") public abstract DataSource.Factory<Integer, Concert> concertsByDate() } VIEW MODEL -------------- // The Integer type argument corresponds to a PositionalDataSource object. val myConcertDataSource : DataSource.Factory<Integer, Concert> =concertDao.concertsByDate() val myPagedList = LivePagedListBuilder(myConcertDataSource, 20).build()
  8. …..ARCHITECTURE - PAGING - DATA Component val myPagingConfig = PagedList.Config.Builder()

    .setPageSize(50) .setPrefetchDistance(150) .setEnablePlaceholders(true) .build() val myPagedList = LivePagedListBuilder(myConcertDataSource, myPagingConfig) .setFetchExecutor(myExecutor) .build() Define your own paging configuration Choose the correct data source type PageSize PageKeyedDataSource Prefetch distance ItemKeyedDataSource Placeholder presence PositionalDataSource
  9. …..ARCHITECTURE - PAGING - DATA Component Build your own datasource

    class MyDataSource : ItemKeyedDataSource<String, Item>() { override fun getKey(item: Item) = item.name override fun loadInitial( params: LoadInitialParams<string>, callback: LoadInitialCallback<Item>) { val items = fetchItems(params.requestedLoadSize) callback.onResult(items) } override fun loadAfter( params: LoadParams<String>, callback: LoadCallback<Item>) { val items = fetchItemsAfter( start = params.key, limit = params.requestedLoadSize) callback.onResult(items) } }
  10. …..ARCHITECTURE - PAGING - DATA Component Update current content For

    Room it happens automatically, but for Refresh action where current DataSource has to be invalidated consider below code class ConcertActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... concertViewModel.refreshState.observe(this, Observer { swipeRefreshLayout.isRefreshing = it == NetworkState.LOADING }) swipeRefreshLayout.setOnRefreshListener { concertViewModel.invalidateDataSource() } } }
  11. …..ARCHITECTURE - PAGING - DATA Component Provide mapping between data

    representations class ConcertViewModel : ViewModel() { val concertDescriptions : LiveData<PagedList<String>> init { val factory = database.allConcertsFactory() .map { concert -> concert.name + " - " + concert.date } concerts = LivePagedListBuilder(factory, 30).build() } } }
  12. …..ARCHITECTURE - PAGING - UI Component class ConcertPagedListAdapter() : PagedListAdapter<Concert,

    ConcertViewHolder>( object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id = newItem.id // Use the "==" operator (or Object.equals() in Java-based code) to know // when an item's content changes. Implement equals(), or write custom // data comparison logic here. override fun areContentsTheSame(oldItem: Concert, newItem: Concert) = oldItem.name == newItem.name && oldItem.date == newItem.date } ) { override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null holder.bind(concert) } }
  13. ARCHITECTURE - WORK MANAGER WorkManager might use JobScheduler, Firebase JobDispatcher,

    or AlarmManager based on API level and App state • Worker: specifies what task you need to perform. The WorkManager APIs include an abstract Worker class. You extend this class and perform the work here. • WorkRequest: represents an individual task. At a minimum, a WorkRequest object specifies which Worker class should perform (Onetime or Periodic) • WorkManager • WorkStatus public class CompressWorker extends Worker { @Override public Worker.WorkerResult doWork() { myCompress(); return WorkerResult.SUCCESS; } } WorkManager.getInstance().getStatusById(compressionWork.getId()) .observe(lifecycleOwner, workStatus -> { if (workStatus != null && workStatus.getState().isFinished()) { ... } });
  14. Android KTX BEFORE view.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun

    onPreDraw(): Boolean { viewTreeObserver.removeOnPreDrawListener(thi s) actionToBeTriggered() return true } }); AFTER view.doOnPreDraw { actionToBeTriggered() }
  15. Android KTX BEFORE supportFragmentManager .beginTransaction() .replace(R.id.my_fragment_container, myFragment, FRAGMENT_TAG) .commitAllowingStateLoss() AFTER

    supportFragmentManager.transaction(allowStateL oss = true) { replace(R.id.my_fragment_container, myFragment, FRAGMENT_TAG) }
  16. ANDROID X - Package refactoring Diivision between APIs that are

    bundled with the platform and which are static libraries for app developers that work across different versions of Android. android.* vs androidx.* namespaces Old New android.support.** androidx.@ android.databinding.** androidx.databinding.@ android.design.** com.google.android.material.@ android.support.test.** (in a future release) androidx.test.@ Old New android.arch.** androidx.@ android.arch.persistence.room.** androidx.room.@ android.arch.persistence.** androidx.sqlite.@
  17. ANDROID X - Migration Per-artifact strict semantic versioning Migration from

    28.0.0-alpha1 android.support to androidx-packaged dependencies has two major parts: source refactoring and dependency translation.
  18. Slices A "slice" is a way to surface your app's

    UI inside of the Google Assistant as a result of a search Your Actions can appear in the Android launcher, Smart Text Selection, the Google Search app, the Google Assistant, and the Play Store.
  19. App Bundle 1. Android App Bundle & Google Play Dynamic

    Delivery 2. Dynamic features via the Android App Bundle 3. Google Play Console 4. Google Play Instant
  20. ANDROID P - Android In Enterprise • Work profile user

    interface ◦ Switch apps across profiles ◦ Programmatically turn work profiles on or off • Lock down any app to a device Android P also extends the lock task APIs to profile owners of affiliated and non-affiliated users. Follow the steps below to lock an app to the screen: ◦ Call DevicePolicyManager.setLockTaskPackages() to whitelist apps for lock task mode. ◦ Call ActivityOptions.setLockTaskEnabled() to launch a whitelisted app into lock task m • Support multiple users on dedicated devices • Clear package data and remove accounts • Restrict sharing into a work profile
  21. ANDROID P - Power Management • App Standby Buckets ◦

    Active ◦ Working set ◦ Frequent ◦ Rare • Background restrictions • Battery saver improvements • Doze