Make better choices while coding

  • Google released an option to include OSS license activity in your app, use that to attribute credits to the OSS libs in your app [Ref Link]

    Checkout a working example here

  • Make Android Studio render <merge> layouts correctly by specifying the layout type with the tools:parentTag attribute [Ref Link]

    diagram

  • Checkout the Background Execution Limits on Android Oreo and update your app to work with the restrictions [Ref Link]

  • To take good screenshots with clean status bar use the Demo Mode in Android [Ref Link]

    • Steps

      1. Enable Demo Mode

        adb shell settings put global sysui_demo_allowed 1
        
      2. Enable/disable icons by running the right command

        // display time 12:00
        adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 1200
        
        // Display full mobile data without type
        adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 4 -e datatype false
        
        // Hide notifications
        adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false
        
        // Show full battery but not in charging state
        adb shell am broadcast -a com.android.systemui.demo -e command battery -e plugged false -e level 100
        
      3. Run app and take screenshots

      4. Exit demo mode once you are done

        adb shell am broadcast -a com.android.systemui.demo -e command exit
        
  • To record video of your android device [Ref Link]

    adb shell && screenrecord /sdcard/download/fileName.mp4
    

    Hit Ctrl+C to exit/stop recording

    Recorded video file is saved at the location mentioned in the command on the device itself.

  • Use Dao inheritance to reduce the amount of boilerplate code [Ref Link]

  • Instead of using getActivity() in fragment, keep a habit of getting context from onAttach(). [Ref Link]

  • Avoid setting a background in every view/fragment as it likely causes overdraw. [Ref Link]

  • View.getWidth() = 0? That's because your view hasn't been layout yet, use globallayoutListener to know layout done. [Ref Link]

  • Android never kills activities, it only kills processes. When low memory the lowest priority ranked will be killed.[Ref Link]

  • Use .([filename].java:[line]) in your log statements to make them clickable in Android Studio and Intellij IDEA.

  • Use -whyareyoukeeping class com.jeroenmols.MyClass to figure out why certain a class wasn't removed.[Ref Link]

  • Use certificate pinning to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates, when making requests from your app. [Ref Link]

  • Do download the latest emulator using CLI

    cd <android_sdk>/tools/bin
    ./sdkmanager --channel=3 emulator
    

    To check the version of emulator, use ./sdkmanager --channel=3 emulator

  • Checkout some tricks when using Android Strings in XML

  • Cleanup your Gradle caches by deleting files not accessed within the last month [Ref Link]

    find ~/.gradle -type f -atime +30 -delete
    find ~/.gradle -type d -mindepth 1 -empty -delete
    

    To check the size of your gradle cache, run: du -sh ~/.gradle

  • Checkout some cool tricks when using tools: attribute in your android layouts, such as sample data and recyclerview item layout previews

  • Remove all debug log statements from the release build using the below proguard rules. (app's build.gradle should have minifyEnabled true set for this to work)

    # Remove all debug logs
    -assumenosideeffects class android.util.Log {
        public static *** d(...);
    }
    

    The above snippet is usually appended to contents of app/proguard-rules.pro file

  • Should I use Enums in Android?

    tl;dr

    • If you need code to be very performant integer constants may be the way to go

      public class Operator {
          public static final int ADD = 1;
          public static final int SUBTRACT = 2;
          public static final int MULTIPLY = 3;
          public static final int DIVIDE = 4;
      }
      
    • Use Enums because

      • Are type-safe, so you can only use valid enum types
      • Provide better code readability
      • Can implement interfaces
      • Support polymorphic behavior
      • In some really trivial cases, Proguard can optimize Enums into integer constants for you [Ref Link]
      • Performance difference rarely makes a difference.
      public enum Operators {
          Add, Subtract, Multiply, Divide
      }
      
  • The string resource android.R.string.yes doesnot yield string "Yes" instead it yields "Ok". Similarly the string resource android.R.string.no doesnot yield string "No" instead it yields "Cancel" [Ref Link]

    string resource

  • Don’t want generated files in your AS search results? Go to Preferences -> File Types -> Ignore files and folders and add the pattern to ignore - e.g. *.dex;*.class; [Ref Link]

  • If you uncheck “Suspend” and check “Evaluate and Log” in breakpoint menu, the breakpoint will print evaluated statement into the uncluttered “Console” window. No need for recompile due to added Log.d statements anymore [Ref Link]

    Breakpoint Logs

  • To measure how long a method took to execute, you can use TimingLogger class. [Ref Link]

    • Typical Usage
      TimingLogger timings = new TimingLogger(TAG, "methodA");
      // ... do some work A ...
      timings.addSplit("work A");
      // ... do some work B ...
      timings.addSplit("work B");
      // ... do some work C ...
      timings.addSplit("work C");
      timings.dumpToLog();
      
    • Output
      D/TAG     ( 3459): methodA: begin
      D/TAG     ( 3459): methodA:      9 ms, work A
      D/TAG     ( 3459): methodA:      1 ms, work B
      D/TAG     ( 3459): methodA:      6 ms, work C
      D/TAG     ( 3459): methodA: end, 16 ms
      
  • If you're working with Android Things and you don't have an extrenal screen for your device, install scrcpy and use it to see what's going on your Android IoT device. It works a charm over wireless adb. [Ref Link]

  • Android Studio has this weird behaviour that it allows to edit its default code style, which leads to a weird side-effect. If you open your pre-setup project(with set codestyle and copyright configs) in Android Studio it will delete all pre-setup codestyle and copyright profile in this project. This is every much evident if you checked in your configs into git for sharing purpose, which is lost immediately as soon as you open the project

    deleted:    .idea/codeStyles/Project.xml
    deleted:    .idea/codeStyles/codeStyleConfig.xml
    deleted:    .idea/copyright/profiles_settings.xml
    deleted:    .idea/copyright/copyright.xml
    

    To fix that please follow along as below: [All thanks to Said Tahsin Dane for the solution]

    • We first need to verify that your Default codestyle isn't modified. To check that please open Android Studio with any project except your pre-setup(with set codestyle and copyright configs) project. Then navigate to Preferences>Edior>Codestyle and check if your code scheme has Default in BLUE color (this means it is modified).

      modified_default

    • However if it is not colored BLUE, you are good and you can go ahead to open your pre-setup(with set codestyle and copyright configs) project and everything should be pre-setup for you.

    • If it is modified (colored BLUE), then click on the cog icon and select Restore Default

      restore_default

    • After you hit that option, simply accept the change

      accept_change

    • Once done, you will see your Default is no more colored BLUE or modified, which means you are good

      unmodified_default

    • Now simply go ahead and open your pre-setup(with set codestyle and copyright configs) project and everything should be pre-setup for you.

  • If you add android:sharedUserId to an already published app, the app data will be cleared for all users that install your upgrade (because Android changes the process). So if you ever intend to use it, you must add it before publishing your app [Ref Link]

  • When opening up methods for testing, use otherwise to still hide it from code complete.[Tweet Link, Ref Link]

    making_methods_visible_for_testing

  • You can group your recent Android Studio projects, and add icons to them [Ref Link]

    group_recent_projects

  • Only build a single configuration to speed up debug builds. [Ref Link]

    build_single_config

  • Avoid the annoying jump to Design tab while editing XML. Prefer XML editor under Settings [Ref Link]

    set_xml_as_preferred

  • Reduce installed app size with android:extractNativeLibs="false" in [Tweet Link, Ref Link]

  • Improve Android Studio code inspections with Thread annotations [Tweet Link, Ref Link]

  • Use adb to put a phone into doze mode for testing [Tweet Link, Ref Link]

  • Use areNotificationsEnabled() from NotificationManagerCompat to detect whether your users blocked your Notifications [Tweet Link, Ref Link]

  • Activity.runOnUiThread is just a convenient wrapper of Handler.post; don't pass around Activity just so you can use it. [Ref Link]

  • Define your interfaces with the highest possible option that will suffice. Don't use an Activity when a Context will do. [Ref Link]

  • If you're not building a replacement for the dialer, use ACTION_DIAL not ACTION_CALL to initiate a call. [Ref Link]

  • Requesting updates from a system service may drain battery, so register for updates in onResume and unregister in onPause. [Ref Link]

  • Hierarchy Viewer won’t run on prod devices, if however u want to run it then follow below steps [Tweet Link, Ref Link]

    running_hierarchy_viewer

  • Variable and init block declaration order in Kotlin, actually matters :) if you want to use a variable inside init {} initialize it before it.

  • When comparing intents it does not compare any extra data included in the intents [Tweet Link, Ref Link]

  • To show a ringtone picker to the user, use the ACTION_RINGTONE_PICKER intent to launch the picker as a subactivity. [Ref Link]

  • Want to remove focusState on an item in GridView? Try: android:listSelector="#00000000" [Ref Link]

  • You can generate the proguard keep rules via the APK Analyzer inside Android Studio. [Ref Link]

    proguard_rules_apk_analyzer

  • When viewing an Android Manifest, there is a tab at the bottom that allows you to see the merged manifest. Use this to inspect the merged manifest and find conflicts. [Ref Link]

    manifest-merged

  • In the APK analyzer in Android Studio, classes/members listed in italic are only references, not definitions. If it's in italics, it's defined in another DEX file (or the SDK). [Ref Link]

    apk_analyzer_ref

  • To be able to write multiline Todo comments, simply indent by 1 tab from second line onwards. [Ref Link]

    multiline_todo_comment

  • You can get rid of a lot of noise in the Logcat, by Right Clicking a selected text > "Fold lines like this" option!. [Ref Link]

    fold_line_like_this

  • You know how you can group ur code inside IDEs such as Android Studio and IntelliJ IDEA by using the region and endregion comment blocks. Turns out you can use the same trick to group inside XML files such as for layout, strings, styles, colors xml files [Ref Tweet]

    region_cmt

  • How many of you have had issue with special characters (&,<, >, etc) in your strings.xml file? Did you know there is an action called "Encode XML/HTML Special Characters" inside Android Studio that can escape those characters for you! [Ref Tweet]

    encode_special_1

    • The option is also avaliable under Edit menu drop down

      encode_special_2

    • In case the issue is in just one line, you can also just ALT+ENTER to get contextual fix.

      encode_special_3