You ve been told lies about Fragments.

Similar documents
UI Fragment.

Tablets have larger displays than phones do They can support multiple UI panes / user behaviors at the same time

ACTIVITY, FRAGMENT, NAVIGATION. Roberto Beraldi

CS 4518 Mobile and Ubiquitous Computing Lecture 5: Rotating Device, Saving Data, Intents and Fragments Emmanuel Agu

CS 528 Mobile and Ubiquitous Computing Lecture 3b: Android Activity Lifecycle and Intents Emmanuel Agu

CHAPTER 4. Fragments ActionBar Menus

Repairing crashes in Android Apps. Shin Hwei Tan Zhen Dong Xiang Gao Abhik Roychoudhury National University of Singapore

Building User Interface for Android Mobile Applications II

CS 528 Mobile and Ubiquitous Computing Lecture 4a: Fragments, Camera Emmanuel Agu

Lesson 3 Transcript: Part 1 of 2 - Tools & Scripting

Fragments and the Maps API

Programming in Android. Nick Bopp

Programming with Android: Android for Tablets. Dipartimento di Scienze dell Informazione Università di Bologna

Static Methods. Why use methods?

CE881: Mobile & Social Application Programming

Activities and Fragments

MITOCW watch?v=w_-sx4vr53m

CS 4518 Mobile and Ubiquitous Computing Lecture 4: Data-Driven Views, Android Components & Android Activity Lifecycle Emmanuel Agu

Fragments were added to the Android API in Honeycomb, API 11. The primary classes related to fragments are: android.app.fragment

Zello Quick Start Guide for Kyocera TORQUE

Chapter One: Getting Started With IBM SPSS for Windows

Multiple devices. Use wrap_content and match_parent Use RelativeLayout/ConstraintLayout Use configuration qualifiers

CS378 - Mobile Computing. Anatomy of an Android App and the App Lifecycle

CS371m - Mobile Computing. More UI Navigation, Fragments, and App / Action Bars

Understanding Application

Lifecycle-Aware Components Live Data ViewModel Room Library

CS371m - Mobile Computing. More UI Action Bar, Navigation, and Fragments

Math Dr. Miller - Constructing in Sketchpad (tm) - Due via by Friday, Mar. 18, 2016

COLLEGE OF ENGINEERING, NASHIK-4

Visualization Insider A Little Background Information

Android. The Toolbar

ORGANIZING YOUR ARTWORK WITH LAYERS

INTRODUCTION. 2

15 Minute Traffic Formula. Contents HOW TO GET MORE TRAFFIC IN 15 MINUTES WITH SEO... 3

Android Basics. Android UI Architecture. Android UI 1

Oracle Cloud. Content and Experience Cloud ios Mobile Help E

Mobile Computing Fragments

Lab 1: Getting Started With Android Programming

Interactive Tourist Map

Keyword research. Keywords. SEO for beginners training Module 2.1. What is a keyword? Head, mid tail and long tail keywords

Oracle Cloud. Content and Experience Cloud Android Mobile Help E

Eventually, you'll be returned to the AVD Manager. From there, you'll see your new device.

Client Code - the code that uses the classes under discussion. Coupling - code in one module depends on code in another module

Here are a couple of warnings to my students who may be here to get a copy of what happened on a day that you missed.

Lesson 9 Transcript: Backup and Recovery

For Volunteers An Elvanto Guide

Lesson 4 Transcript: DB2 Architecture

Arduino IDE Friday, 26 October 2018

Syllabus- Java + Android. Java Fundamentals

EMBEDDED SYSTEMS PROGRAMMING UI and Android

Connecting your Plugin Control Panel to your BT Plugin Code

Excel programmers develop two basic types of spreadsheets: spreadsheets

Using PowerPoint - 1

Google Maps Troubleshooting

Minds-on: Android. Session 2

How to Improve Your Campaign Conversion Rates

CS 162 Operating Systems and Systems Programming Professor: Anthony D. Joseph Spring 2002

Introduction To JAVA Programming Language

Foundations, Reasoning About Algorithms, and Design By Contract CMPSC 122

HCA Tech Note 120. Configuring the Control UI Home Page. Option 1: HCA constructs the home page

Produced by. Mobile Application Development. David Drohan Department of Computing & Mathematics Waterford Institute of Technology

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

The SD-WAN security guide

Activities. Repo:

Keep Track of Your Passwords Easily

Guide - The limitations in screen layout using the Item Placement Tool

MITOCW watch?v=flgjisf3l78

ACTIVITY, FRAGMENT, NAVIGATION. Roberto Beraldi

SLACK. What is it? How do I use It?

Produced by. Mobile Application Development. David Drohan Department of Computing & Mathematics Waterford Institute of Technology

Without further ado, let s go over and have a look at what I ve come up with.

Data structures. Priority queues, binary heaps. Dr. Alex Gerdes DIT961 - VT 2018

Your . A setup guide. Last updated March 7, Kingsford Avenue, Glasgow G44 3EU

P1_L3 Operating Systems Security Page 1

Mobile Computing Professor Pushpedra Singh Indraprasth Institute of Information Technology Delhi Andriod Development Lecture 09

GUI Design for Android Applications

Intro To Excel Spreadsheet for use in Introductory Sciences

LECTURE NOTES OF APPLICATION ACTIVITIES

CS378 -Mobile Computing. Anatomy of and Android App and the App Lifecycle

Clickteam Fusion 2.5 Creating a Debug System - Guide

Introduction. Watch the video below to learn more about getting started with PowerPoint. Getting to know PowerPoint

Rsyslog: going up from 40K messages per second to 250K. Rainer Gerhards

Data Structures and Algorithms Dr. Naveen Garg Department of Computer Science and Engineering Indian Institute of Technology, Delhi.

Part 1: Understanding Windows XP Basics

Ackworth Howard Church of England (VC) Junior and Infant School. Child-friendly GDPR privacy notice

learn programming the right way

This is a separate window in the software so if you wish to return to the main screen, just close this window by clicking X in the upper right corner.

We re working full time this summer alongside 3 UCOSP (project course) students (2 from Waterloo: Mark Rada & Su Zhang, 1 from UofT: Angelo Maralit)

Understand applications and their components. activity service broadcast receiver content provider intent AndroidManifest.xml

Replication. Feb 10, 2016 CPSC 416

KTH Royal Institute of Technology SEMINAR 2-29 March Simone Stefani -

IPv6: Are we really ready to turn off IPv4? Geoff Huston APNIC

IMPORTANT: Review the Quick Start Guide on page 3 of this document. Steps 1 15 are critical to ensure the security of this application.

I CALCULATIONS WITHIN AN ATTRIBUTE TABLE

This chapter is intended to take you through the basic steps of using the Visual Basic

Taskbar: Working with Several Windows at Once

Flash offers a way to simplify your work, using symbols. A symbol can be

More About WHILE Loops

UXD. using the elements: structure

CheckBook Pro 2 Help

Transcription:

You ve been told lies about Fragments.

Mateusz Herych Android Tech Lead @ IG Google Developer Expert on Android GDG Kraków co-organizer Father of twins @mherych / github.com/partition

You ve been told lies about Fragments.

Custom Views are all you need.

Custom Views are all you need?

Goals of this talk

Agenda - First I will tell you why Fragments are bad

Agenda - First I will tell you why Fragments are bad Then that you can do nothing about it

Agenda - First I will tell you why Fragments are bad Then that you can do nothing about it Finally will tell you that ACTUALLY you can do something about it

Goals of this talk - For those of your who re locked to Fragments: perhaps teach you something new and share experience how to make your life easier.

Goals of this talk - For those of your who re locked to Fragments: perhaps teach you something new and share experience how to make your life easier. For those of you starting a new project: give an idea about alternative approaches that may possibly work for you (or not).

Fragments, the bad.

Lifecycle.

Advocating Against Android Fragments Pierre-Yves Ricau, Square https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97

Finally getting rid of Android Fragments Sebastian Drygalski, SoftwareMill https://softwaremill.com/finally-getting-rid-of-android-fragments/

Is that a problem though?

Too much drama about number of callbacks. Real issue = unexpected behavior.

Story of an app.

USFragment EuropeFragment AsiaFragment

USFragment { us : [ <us news go here> ], eu : [ <eu news go here>], asia : [ <asia news go here>] EuropeFragment } AsiaFragment

USFragment { us : [ <us news go here> ], eu : [ <eu news go here>], asia : [ <asia news go here>] EuropeFragment } AsiaFragment setusnews() Activity Presenter seteunews() setasianews()

USFragment { EuropeFragment us : [ <us news go here> ], eu : [ <eu news go here>], asia : [ <asia news go here>] findfragmentbytag( us ) + cast + setitems() } AsiaFragment setusnews() Activity Presenter seteunews() setasianews()

Response is cached in memory once done. USFragment { EuropeFragment us : [ <us news go here> ], eu : [ <eu news go here>], asia : [ <asia news go here>] findfragmentbytag( us ) + cast + setitems() } AsiaFragment setusnews() Activity Presenter seteunews() setasianews()

What s the problem?

Activity.onCreate() -> presenter.attachview(view)

Data is cached -> immediate call to Activity.setData()

Activity.setData() -> getfragment().setdata()

View is not yet created.

View is not yet created. NPE inside of the Fragment.

FragmentTransactions are asynchronous.

Quiz

Fragment.onAttach() Fragment.onCreate() Fragment.onCreateView() Activity.onCreate() Activity.onStart()

Activity.onCreate()

Activity.onCreate() Fragment.onAttach()

Activity.onCreate() Fragment.onAttach() Fragment.onCreate()

Activity.onCreate() Fragment.onAttach() Fragment.onCreate() Activity.onStart()

Activity.onCreate() Fragment.onAttach() Fragment.onCreate() Activity.onStart() Fragment.onCreateView()

commitnow() - added June 2016, Support Library 24.0.0

Changes nothing here.

However

This is pretty fundamentally WAI as things stand today. We don't create the view until we transition to the ACTIVITY_CREATED state, which is after the activity oncreate returns. This way a fragment's oncreateview can rely on its host activity having been fully created when it runs. If you commitnow() in oncreate, you haven't reached ACTIVITY_CREATED yet, so the view doesn't get created. https://issuetracker.google.com/issues/37132323

tl;dr - Works As Intended

Activity.onCreate() Fragment.onAttach() Fragment.onCreate() NestedFragment.onAttach() NestedFragment.onCreate()

Activity.onStart() Fragment.onCreateView() Fragment.onViewCreated() Fragment.onActivityCreated() performactivitycreated() NestedFragment.onCreateView() NestedFragment.onViewCreated() NestedFragment.onActivityCreated()

But...

Declaring Fragments in XML

Declaring Fragments in XML

LayoutInflater.Factory

Activity.onCreate() Fragment.onAttach() Fragment.onCreate() NestedFragment.onAttach() NestedFragment.onCreate()

Activity.onCreate() Fragment.onAttach() Fragment.onCreate() NestedFragment.onAttach() NestedFragment.onCreate()

In case your Fragment is inflated via XML, its View is created before setcontentview() returns.

Conclusions

Conclusions - The earliest Activity s callback in which you can rely on your Fragments views being created is onstart().

Conclusions - The earliest Activity s callback in which you can rely on your Fragments views being created is onstart(). The earliest Fragment s callback in which you can rely on your children Fragments views being created is onstart().

Conclusions - The earliest Activity s callback in which you can rely on your Fragments views being created is onstart(). The earliest Fragment s callback in which you can rely on your children Fragments views being created is onstart(). Oh, and in case you inflate Fragments via XML then it works completely different.

Move Presenter.attachView( ) to onstart()?

ViewPager

Problem: tracking screens to Google Analytics

setuservisiblehint()

setuservisiblehint() is unrelated to the regular lifecycle.

setuservisiblehint() can be called before or after your View is created.

setuservisiblehint() can be called before or after your Fragment is attached.

Problem: I have a heavy View, I don t want to destroy when I navigate.

Heavy Fragment A Fragment B

show() / hide() attach() / detach() add() / remove()

show() / hide()

Called when the fragment is visible to the user and actively running. This is generally tied to Activity.onResume of the containing Activity's lifecycle. https://developer.android.com/reference/android/app/f ragment.html#onresume()

Called when the fragment is visible to the user and actively running. This is generally tied to Activity.onResume of the containing Activity's lifecycle. https://developer.android.com/reference/android/app/f ragment.html#onresume()

Hidden Fragment is still in running state.

onhiddenchanged()

Beware: not called on configuration change, so you re left with ishidden().

Debugging

Lessons learned

Lessons learned - Don t use Fragments in case they don t work on their own - i.e. their are being used as Views.

Lessons learned - Don t use Fragments in case they don t work on their own - i.e. their are being used as Views. E.g. they don t have their own Presenters, but rather wait for the data being dispatched from Activity / parent Fragment

Lessons learned - Don t use Fragments in case they don t work on their own - i.e. their are being used as Views. E.g. they don t have their own Presenters, but rather wait for the data being dispatched from Activity / parent Fragment If you need to talk to your Fragment from your Activity / parent Fragment give it a second thought.

Lessons learned - Don t use Fragments in case they don t work on their own - i.e. their are being used as Views. E.g. they don t have their own Presenters, but rather wait for the data being dispatched from Activity / parent Fragment If you need to talk to your Fragment from your Activity / parent Fragment give it a second thought. If any of the above is true, just go for custom views - in such cases they re equally reusable.

General rule of thumb - Casting getactivity() to some callback interface + invoking methods is more-or-less safe.

General rule of thumb - Casting getactivity() to some callback interface + invoking methods is more-or-less safe. (at least if you know what you re doing)

General rule of thumb - Casting getactivity() to some callback interface + invoking methods is more-or-less safe. (at least if you know what you re doing) Same for gettargetfragment() / getparentfragment()

General rule of thumb - Casting getactivity() to some callback interface + invoking methods is more-or-less safe. (at least if you know what you re doing) Same for gettargetfragment() / getparentfragment()

General rule of thumb - - Casting getactivity() to some callback interface + invoking methods is more-or-less safe. (at least if you know what you re doing) Same for gettargetfragment() / getparentfragment() Delegating calls from Activity / parent Fragment to Fragments stored within theirs FragmentManagers is less safe, as there s less certainty what state they re in.

Ok, but do we really need Fragments at all?

Fragments, the good.

Fragments, the good. - Backstack + animations

Fragments, the good. - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here)

Fragments, the good. - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here) requestpermissions / startactivityforresult - if started from Fragments, FragmentActivity/FragmentManager delegate them directly to the Fragment that needs them - no need for dispatching

Fragments, the good. - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here) requestpermissions / startactivityforresult - if started from Fragments, FragmentActivity/FragmentManager delegate them directly to the Fragment that needs them - no need for dispatching (finally!)

startactivityforresult() in Fragments Fragment.startActivityForResult(intent, 0)

startactivityforresult() in Fragments Fragment.startActivityForResult(intent, 0) Dispatched to Activity as Activity.startActivityForResult(intent, 65536)

startactivityforresult() in Fragments Fragment.startActivityForResult(intent, 0) Dispatched to Activity as Activity.startActivityForResult(intent, 65536) Then Activity.onActivityResult() is called, with requestcode = 65536.

startactivityforresult() in Fragments Fragment.startActivityForResult(intent, 0) Dispatched to Activity as Activity.startActivityForResult(intent, 65536) Then Activity.onActivityResult() is called, with requestcode = 65536. And delegated futher by Activity to a Fragment with requestcode = 0.

startactivityforresult() in Fragments Fragment.startActivityForResult(intent, 0) Dispatched to Activity as Activity.startActivityForResult(intent, 65536) Then Activity.onActivityResult() is called, with requestcode = 65536. And delegated futher by Activity to a Fragment with requestcode = 0. Half of the bits are used to identify target Fragment, the other half is actual requestcode requested by that Fragment.

Fragments, the good. - - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here) requestpermissions / startactivityforresult - if started from Fragments, FragmentActivity/FragmentManager delegate them directly to the Fragment that needs them - no need for dispatching (finally!) They re in supportlib, no need to deal with platform-bugs that will be there forever (as once something gets shipped in SDK, it ll stay there forever).

Fragments, the good. - - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here) requestpermissions / startactivityforresult - if started from Fragments, FragmentActivity/FragmentManager delegate them directly to the Fragment that needs them - no need for dispatching (finally!) They re in supportlib, no need to deal with platform-bugs that will be there forever (as once something gets shipped in SDK, it ll stay there forever). In case you get in trouble - there are 10000 other people in the same situation.

Fragments, the good. - - Backstack + animations Retaining on configuration changes (and I m not talking about retained Fragments here) requestpermissions / startactivityforresult - if started from Fragments, FragmentActivity/FragmentManager delegate them directly to the Fragment that needs them - no need for dispatching (finally!) They re in supportlib, no need to deal with platform-bugs that will be there forever (as once something gets shipped in SDK, it ll stay there forever). In case you get in trouble - there are 10000 other people in the same situation. Communication to parent / target - e.g. settargetfragment() is retained for you on configuration changes.

Fragments, the good - View-less Fragments - e.g. for the purposes of managing your options menu or Toolbar

Your current balance, streamed in real-time by WebSocket Some data, e.g. charts $ 12,500

Fragments, the good - View-less Fragments - e.g. for the purposes of managing your options menu or Toolbar Nested Fragments are sometimes helpful - imagine Activity with Bottom Bar tabs, where each tab has its own backstack. (vide Instagram)

Fragments, the good - View-less Fragments - e.g. for the purposes of managing your options menu or Toolbar Nested Fragments are sometimes helpful - imagine Activity with Bottom Bar tabs, where each tab has its own backstack. (vide Instagram) Better callbacks than just a View - you may not need them, but once you need them you end-up delegating lifecycle methods to your custom views.

tl;dr not something you should write on your own.

So I started to look for alternatives.

Requirements

Requirements - Supports backstack (including nested backstacks), together with backstack animations

Requirements - Supports backstack (including nested backstacks), together with backstack animations Synchronous transactions

Requirements - Supports backstack (including nested backstacks), together with backstack animations Synchronous transactions Retaining states on configuration changes

Requirements - Supports backstack (including nested backstacks), together with backstack animations Synchronous transactions Retaining states on configuration changes Some settargetfragment() equalvement would be nice

Requirements - Supports backstack (including nested backstacks), together with backstack animations Synchronous transactions Retaining states on configuration changes Some settargetfragment() equalvement would be nice Fragment-like support for requestpermissions() and startactivityforresult()

Requirements - Supports backstack (including nested backstacks), together with backstack animations Synchronous transactions Retaining states on configuration changes Some settargetfragment() equalvement would be nice Fragment-like support for requestpermissions() and startactivityforresult Well maintained, reasonably big user-base.

Basically all I needed were Fragments, but synchronous.

Conductor https://github.com/bluelinelabs/conductor

Controllers are your new Fragments

Controller.java oncreateview() onattach() ondetach() ondestroyview() ondestroy()

Controller.java sethasoptionsmenu() oncreateoptionsmenu() getactivity() startactivity() / startactivityforresult() / onactivityresult() requestpermissions() / onrequestpermissionsresult()

Whole transaction is executed & your Controller s view is created before this call returns.

Nested transactions are synchronous as well

D/ControllerRetaining: com.bluelinelabs.conductor.demo.controllers.homecontroller@7cea9cc

D/ControllerRetaining: com.bluelinelabs.conductor.demo.controllers.homecontroller@7cea9cc Then, after orientation change: D/ControllerRetaining: com.bluelinelabs.conductor.demo.controllers.homecontroller@7cea9cc

Same behavior as for Fragments with setretaininstance(true)

Interestingly, Routers state is being kept in a retained Fragment.

Oh, irony!

You still need to save your controller s custom state in onsaveviewstate(). e.g. Don t Keep Activities

Target Controller can be in any Router - root or child routers.

Wait, what?

Conductor, by default, destroys Views once their Controllers get detached.

This is executed on a controller that has its View destroyed.

startactivityforresult

Each Controller has its own, unique instanceid (UUID generated during construction)

Goes recursively - looks up child Routers as well

ViewPager

You may ve noticed: no visibility callback in Controllers whatsoever.

Which means: N controllers are in attached state depending on Pager s offscreen page limit.

My first reaction: Damn, this is even worse than Fragments then!

Not really!

Disadvantages

Disadvantages - Controllers must have Views and need to be attached to some container.

Disadvantages - Controllers must have Views and need to be attached to some container. Using Fragments may still be necessary (or simply: easier) - e.g. SupportMapFragment.

Disadvantages - Controllers must have Views and need to be attached to some container. Using Fragments may still be necessary (or simply: easier) - e.g. SupportMapFragment. Doing Dialogs is bit hacky

Disadvantages - Controllers must have Views and need to be attached to some container. Using Fragments may still be necessary (or simply: easier) - e.g. SupportMapFragment. Doing Dialogs is bit hacky User base is still not even comparable to Fragments - it s quite hard to Google a solution if you step into something unexpected. (Though Conductor s author is super-responsive on Github)

Conclusions.

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views I mean, they can, but then you start reinventing the wheel (e.g. backstack, delegation of onactivityresult/onpermissionsresult callbacks)

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views I mean, they can, but then you start reinventing the wheel (e.g. backstack, delegation of onactivityresult/onpermissionsresult callbacks) Fragments are okay-ish if you use them carefully and understand how they work

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views I mean, they can, but then you start reinventing the wheel (e.g. backstack, delegation of onactivityresult/onpermissionsresult callbacks) Fragments are okay-ish if you use them carefully and understand how they work Lots of issues in Fragments are caused by bugs that will eventually get fixed. Remember that no alternative is bug-free.

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views I mean, they can, but then you start reinventing the wheel (e.g. backstack, delegation of onactivityresult/onpermissionsresult callbacks) Fragments are okay-ish if you use them carefully and understand how they work Lots of issues in Fragments are caused by bugs that will eventually get fixed. Remember that no alternative is bug-free. And the most important one...

Conclusions - For majority of apps Fragments can t be exchanged for Custom Views I mean, they can, but then you start reinventing the wheel (e.g. backstack, delegation of onactivityresult/onpermissionsresult callbacks) Fragments are okay-ish if you use them carefully and understand how they work Lots of issues in Fragments are caused by bugs that will eventually get fixed. Remember that no alternative is bug-free. And the most important one Don t follow blindly someone telling you that X sucks and you shouldn t use it. :-)

Thanks - Q & A