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

Crashing is good for your app

Crashing is good for your app

As Android devs, we are usually too afraid of the crash. We go way too far to avoid crashing.

Sometimes our motto is no Crash at all costs.

Wrapping all of our java objects in double null checks, Elvis (?:) operators everywhere, absolutely no double bang (!!), "try-catch" everything.

These are just a few samples of what we do to avoid that innocent crash.

I'm here to tell you to stop.
We should let our crashes happen. I'll show you how they are useful and help us build better and safer apps.
Removing all of them does not help our apps or users.

I explain why it's bad to stop crashing at all costs.

Let's crash!!!

Slides with Animations:
https://bit.ly/3nQVbdv

Seyed Jafari

November 01, 2021
Tweet

More Decks by Seyed Jafari

Other Decks in Technology

Transcript

  1. What is a CRASH 💥 Wiki: In computing, a crash,

    occurs when a software application stops functioning properly and exits. Me: When a program stops working unexpectedly
  2. Exception Techopedia: An exception is an abnormal or unprecedented event

    that occurs after the execution of a software program or application. It is a runtime error of an undesired result or event affecting normal program flow.
  3. Exceptions for exceptionals! When something terribly goes wrong. It’s unacceptable.

    No way! Does not meet the rules. Simple Example: var result = 1 / 0
  4. Famous exceptions/errors we all know 1. NullPointerException 2. IOException 3.

    OutOfMemoryError 4. StackOverflowError Kotlin/Native InvalidMutabilityException
  5. fun getBookNames(libraryId : String): Data<Error, List<String>> = try { Data.Success(fetchBookNames(libraryId))

    }catch(e : IOException) { Data.Failed(e) } NetworkRequests AwesomeRepository.kt Catching example
  6. Enum mappings Good Exceptions enum class LightSwitchState{ ON, OFF, UNKNOWN,

    } fun mapStateToEnum(state : String): LightSwitchState = LightSwitchState .values() .find { it.name == state } ?: UNKNOWN
  7. Enum mappings Good Exceptions enum class LightSwitchState{ ON, OFF, }

    fun mapStateToEnum(state : String): LightSwitchState? = LightSwitchState .values() .find { it.name == state }
  8. Enum mappings Good Exceptions enum class LightSwitchState{ ON, OFF, }

    fun mapStateToEnum(state : String): LightSwitchState = LightSwitchState .values() .first { it.name == state }
  9. var binding: FragmentAwesomeBinding? = null ViewBinding vs Fragments AwesomeFragment.kt Good

    Exceptions fun setTitle(txt : String) { binding?.title.text = txt }
  10. var _binding: FragmentAwesomeBinding? = null val binding get() = _binding!!

    fun onViewCreated(view: View) { _binding = FragmentAwesomeBinding.bind(view) } fun onViewDestroyed(view: View){ _binding = null } fun setTitle(txt : String) { binding.title.text = txt } ViewBinding vs Fragments AwesomeFragment.kt Good Exceptions
  11. Good Exceptions var _binding: FragmentAwesomeBinding? = null val binding get()

    = _binding!! fun onViewCreated(view: View) { _binding = FragmentAwesomeBinding.bind(view) } fun onViewDestroyed(view: View){ _binding = null } fun setTitle(txt : String) { binding.title.text = txt } ViewBinding vs Fragments AwesomeFragment.kt
  12. var _binding: FragmentAwesomeBinding? = null val binding get() = _binding!!

    fun onViewCreated(view: View) { _binding = FragmentAwesomeBinding.bind(view) } fun onViewDestroyed(view: View){ _binding = null } fun setTitle(txt : String) { binding.title.text = txt } ViewBinding vs Fragments AwesomeFragment.kt Good Exceptions
  13. Good Exceptions Business logics and specs fun packThreeBooks(books : List<Book>):

    BookPack { require(books.size == 3){ "we need exactly three books to pack" } return packageBooks(books) }
  14. Catching exceptions Safe layering the good exceptions fun getBooksAndPackThem(library :

    Library) : BookPack? { val books = library.getBooks() return try{ packThreeBooks(books) }catch(e: Exception){ null } }
  15. BUT

  16. Exception is bad for UX, Let’s Fix it 1. Try-Catch

    everything 2. Add Safe Layers 3. Set Thread Uncaught Exception handlers We are safe now!
  17. I/Fitness: OnPackageChangedOperation got intent: Intent... I/Icing: Indexing com.google.android.gms-apps from com.google.android.gms

    [CONTEXT service_id=21 ] I/Icing: Indexing done com.google.android.gms-apps [CONTEXT service_id=21 ] I/Telecom: DefaultDialerCache: Refreshing default dialer for user 0: now com.android.dialer: DDC.oR@AI8 I/system_server: Background young concurrent copying GC freed 80900(4601KB) AllocSpace objects, 11(1124KB) LOS objects, 11% free, 31MB/35MB, paused 458us total 142.940ms I/CarrierSvcBindHelper: No carrier app for: 0 I/Fitness: FitCleanupIntentOperation received Intent android.intent.action.PACKAGE_CHANGED I/Fitness: OnPackageChangedOperation got intent: Intent... I/Icing: Indexing com.google.android.gms-apps from com.google.android.gms [CONTEXT service_id=21 ] I/Icing: Indexing done com.google.android.gms-apps [CONTEXT service_id=21 ] I/Fitness: FitCleanupIntentOperation received Intent android.intent.action.PACKAGE_CHANGED Logging issues Dear Logcat indistinct
  18. I/Fitness: OnPackageChangedOperation got intent: Intent... I/Icing: Indexing com.google.android.gms-apps from com.google.android.gms

    [CONTEXT service_id=21 ] I/Icing: Indexing done com.google.android.gms-apps [CONTEXT service_id=21 ] I/Telecom: DefaultDialerCache: Refreshing default dialer for user 0: now com.android.dialer: DDC.oR@AI8 I/system_server: Background young concurrent copying GC freed 80900(4601KB) AllocSpace objects, 11(1124KB) LOS objects, 11% free, 31MB/35MB, paused 458us total 142.940ms I/CarrierSvcBindHelper: No carrier app for: 0 I/Fitness: FitCleanupIntentOperation received Intent android.intent.action.PACKAGE_CHANGED I/Fitness: OnPackageChangedOperation got intent: Intent... I/Icing: Indexing com.google.android.gms-apps from com.google.android.gms [CONTEXT service_id=21 ] I/Icing: Indexing done com.google.android.gms-apps [CONTEXT service_id=21 ] I/Fitness: FitCleanupIntentOperation received Intent android.intent.action.PACKAGE_CHANGED Logging issues Dear Logcat indistinct
  19. java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:683) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:513) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:889)

    at android.content.res.Resources.loadDrawable(Resources.java:3436) at android.content.res.Resources.getDrawable(Resources.java:1909) at android.view.View.setBackgroundResource(View.java:16251) at com.autkusoytas.bilbakalim.SoruEkrani.cevapSecimi(SoruEkrani.java:666) at com.autkusoytas.bilbakalim.SoruEkrani$9$1.run(SoruEkrani.java:862) at android.os.Handler.handleCallback(Handler.java:733) ….. Exceptions advantage Dear Logcat Easily distinguishable
  20. • V: Verbose. • D: Debug. • I: Info. •

    W: Warning. • E: Error. • A: Assert. Logging issues Android SDK Hard to choose
  21. Exceptions advantage Java std throwables Clear types • java.lang.NullPointerException •

    java.io.IOException • java.lang.IllegalStateException • java.lang.IllegalArgumentException • java.lang.OutOfMemoryError • java.lang.StackOverflowError
  22. tag= MainActivity::class.simpleName, msg= "some f… thing went wrong", tr= null

    Logging issues Logcat.d Manual INFO gathering ) Log.d(
  23. • Checking logs regularly (usually ignored) • Finding the right

    one (find a needle in a haystack) • Setting severity level • Assigning to the right team • Velocity Alerts Logging issues Slow & Hard Addersing
  24. Exceptions advantage Fast & Easy Addersing • They are highly

    prioritised (fixed even during weekends! 󰣻) • Usually delivered to devs inbox • They can be assigned automatically • Types can be used as Severity • Alerts already set (Crashlytics)
  25. Exceptions advantage Exception reporting services Most of the services are

    free • Crashlytics • Sentry • Yandex • Bugsnag
  26. 💥 Happy Crashing 💥 @worldsnas Reach out to me about

    your crashes 🤗 Thanks We are actively hiring in wide range of positions. make sure to checkout our openings on: https://www.revolut.com/careers