nisrulz / android-tips-tricks
- пятница, 24 марта 2017 г. в 03:12:29
Java
☑️ [Cheatsheet] Tips and tricks for Android Development
Also included in
Cheatsheet about tips and tricks for Android Development
This is a simple set of tips and tricks regarding Android Development which I have gathered from various sources. It helps me direct other android devs in my community regarding stuff each android dev should know about. It is also there for me to keep track of anything I either learn on my own or from other sources now and then when browsing the internet.
Contributions are always welcome, hoping people will help me in growing this. To contribute, simply open up a PR with the changes.
Code faster by using keyboard shortcuts
Description | Mac | Linux/Win |
---|---|---|
Lookup IDE commands | Cmd+Shift+A | Ctrl+Shift+A |
Open Class | Cmd+O | Ctrl+O |
Open File | Cmd+Shift+O | Ctrl+Shift+N |
Open recently edited file | Cmd+Shift+E | Ctrl+Shift+E |
Lookup Actions | Cmd+Shift+A | Ctrl+Shift+A |
Open Symbol | Cmd+Opt+O | Alt+Shift+N |
Open recently used file | Cmd+E | Ctrl+E |
Last Edited Location | Cmd+Shift+Backspace | Ctrl+Shift+Backspace |
Find Usage in persistent window | Opt+F7 | Alt+F7 |
Find Usage in floating window | Cmd+Opt+F7 | Ctrl+Alt+F7 |
Format the code with proper Indentation | Cmd+Opt+L | Ctrl+Alt+L |
Surround With | Opt+Cmd+T | Alt+Ctrl+T |
Open Terminal | Opt+F12 | Alt+F12 |
Generate Setter/Getters | Cmd+N | Alt+Ins |
Find Class | CMD+O | Ctrl+N |
Refactor/Rename | Shift+F6 | Shift+F6 |
Quick Fix | Opt+Enter | Alt+Enter |
Goto Definition | Cmd+B | Ctrl+B |
Show parameters for selected method | Cmd+P | Ctrl+P |
Refactor This | Ctrl+T | Ctrl+Alt+Shift+T |
Stop Process | Cmd+F2 | Ctrl+F2 |
Search Everywhere | Shift+Shift | Shift+Shift |
Select Methods to Override | Ctrl+O | Ctrl+O |
Delete Line | Cmd+Backspace | Ctrl+Y |
Duplicate Line | Cmd+D | Ctrl+D |
Grow/Shrink selection from cursor | Opt+Up/Down Arrow key | Shift+Ctrl+W |
Multicursor Selection | Ctrl+G | Alt+J |
Use plugins to become more efficient
The plugin basically will annoy the hell out of you by showing you a big screen overlay with the key combination you should have used, if you used your mouse to execute some command to a level when you basically would start using the key combination just to avoid KeyPromoter annoying you all the time. It also has some useful features, like it will prompt you to create a key binding for a command whenever an action does not have a key binding and you have used it 3 times using your cursor.
Provides actions for text manipulation such as Toggle case, encode/decode, sorting,
Add Sort Lines action in Edit menu to sort selected lines or whole file if the selection is empty.
Provides static byte code analysis to look for bugs in Java code from within Android Studio
The plugin that provides on-the-fly feedback to developers on new bugs and quality issues injected into Java, JavaScript and PHP code.
The plugin provides both real-time and on-demand scanning of Java files from within Android Studio.
The plugin that adds ADB commands to Android Studio and IntelliJ such as ADB Uninstall App, ADB Kill App, ADB Restart App, etc
The plugin which helps you find and implement the code you require in an instant.
The Dagger IntelliJ plugin creates visual connections between a @Inject object and the @Provides method that creates it.
This plugin extends the built-in JVM debugger with capabilities to explore objects in the JVM heap during a debug session.
Use Live Templates in Android Studio
newInstance
- Generates the static newInstance
function inside a FragmentToast
- Generates Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
fbc
- findViewById with castconst
- Define a android style int constantlogd
- Generates Log.d(TAG, "");
logm
- Log current method name and its arguments.logr
- Log result of the current methodlogt
- static logtaf with current classnamepsf
- public static finalsout
- Prints a string to System.outsoutm
- Prints current class and method names to System.outsoutp
- Prints method parameter names and values to System.outvisible
- Set view visibility to VISIBLEgone
- Set view visibility to GONEnoInstance
- private empty constructor to prohibit instance creationPostfix code completion in Android Studio
Android Studio/IntelliJ havea special kind of code completion which allows you to write code specific to a field
<expr>.null
will auto complete to if(<expr> == null)
<expr>.nootnull
will auto complete to if(<expr> != null)
<expr>.var
will auto complete to T name = <expr>
<expr>.field
will auto complete to create a global field variable field = <expr>
<ArrayExpr>.for
will auto complete to for(T item : <Arrayexpr>)
<ArrayExpr>.fori
will auto complete to for(int i = 0; i < <Arrayexpr>.length; i++)
<ArrayExpr>.forr
will auto complete to for(int i = <Arrayexpr>.length - 1; i > 0 ; i--)
Complete list of available postfix code completion can be found at Settings → Editor → Postfix Templates
Use the Darcula Theme in Android Studio
Ok, I know its more like a preference, but trust me using that keeps your eyes less strained as they would be if you used the Default Light theme.
Don't use a small font
Preferably use a font in Android Studio that's easy to read and is at a font size which does not forces you to strain your eyes. I use Menlo font.
Use a code style
You should use a standard codestyle, so possible contenders can be
Use the Memory/Network/CPU Monitor inside Android Studio to profile your code/app
Apart from using physical devices, one should use emulators as they are as of now easy to manage and equivalently powerful.
This one needs special mention due to how useful it is. It basically is a window to your device i.e it streams and allows you to interact with your physical device on your laptop. Very useful when you are demoing your app during a presentation. You can interact with your physical device and it will be shown right in your laptop screen. It has a paid/free version, paid version is totally worth buying.
Yes, vysor was great, but if you want to share your keyboard and mouse directly to your Android device, then this app is for you. It enables you to control your Android device as if it was part of your desktop computer. The FREE version includes the use of computer mouse, while the PRO version includes features such as use of keyboard. This is useful where you can test your app without your hands ever leaving your keyboard.
Use OkHttp over HttpUrlConnect
HttpUrlConnect suffers from quite some bugs. Okhttp solves them in a more elegant manner. [Reference Link]
Reference local aar
files as below [Stackoverflow Ref]
dependencies {
compile(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
}
repositories{
flatDir{
dirs 'libs'
}
}
Use Pidcat for a better log reading experience
Use some Version Control System(VCS) like Git
Use ClassyShark
It is a standalone tool for Android Devs used to browse any Android executable and show important info such as class interfaces and members, dex counts and dependencies
Use Stetho
Debug your android apps using Chrome Dev Tools. Includes tools like Network Monitor, Shared Preference explorer etc.
A tool to analyze battery consumers using Android "bugreport" files.
Always use a constant version value like "1.2.0"
Avoid using +
when specifying the version of dependencies.
Do not use your own personal email for Google Play Developer Account
Use Vectors instead of PNG
If you do have to use png, compress them. Take a look at TinyPNG.
Use proguard
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Use shrinkResources
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
...
}
}
}
Simulating Android killing your app in the background, run in terminal
adb shell am kill
Follow the below rule to have faster gradle builds
Gradle memory >= Dex memory + 1Gb
Split your apk using gradle when using Native code, do not bundle all of em together and ship!.. coz that will make you evil
defaultConfig {
...
ndk {
abiFilters "armeabi", "armeabi-v7a", "mips", "x86"
}
}
//Split into platform dependent APK
splits {
abi {
enable true
reset()
include 'armeabi', 'armeabi-v7a', 'mips', 'x86' //select ABIs to build APKs for
universalApk false //generate an additional APK that contains all the ABIs
}
}
// map for the version code
project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'mips': 5, 'x86': 8]
// Rename with proper versioning
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
output.versionCodeOverride =
project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) *
1000000 +
android.defaultConfig.versionCode
}
}
Learn about some architecture such as MVP or Clean
Try to understand and follow TDD (Test Driven Development)
To force re-download of dependencies
./gradlew --refresh-dependencies
To exclude a certain task from being run by gradle
Suppose you want to exclude the task javaDoc
then use -x
option followed by the task name, i.e javaDoc
in this case.
./gradlew clean build -x javaDoc
To have the each subproject script name match that of the project name
Then add this line in settings.gradle
rootProject.children.each{
it.buildFileName = it.name + '.gradle'
}
Follow the DRY principle DRY = Do not Repeat Yourself
Learn about Dependency Resolution
With the speed android dependencies update, sooner or later you are going to encounter some sort of dependency conflict. The solution is making use of Dependency Resolution. Official Reference
Use different package name for non-release builds
android {
buildTypes {
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
}
release {
// ...
}
}
}
Make use of custom gradle tasks in your build.gradle files
Android uses Gradle as its build system, which actually allows one to make a lot of things easy by creating tasks to automate things. This reddit post enlists a lot of such useful gradle scripts
Use a proper .gitignore in your Android Projects, Check it here
Use LeakCanary to detect memory leaks in your app - Its a memory leak detection library for Android and Java.
Speed up your gradle builds in Android Studio 2.3+
Switch to gradle 3.4.1
Run this inside your project folder to update your gradle wrapper
./gradlew wrapper --gradle-version 3.4.1 --distribution-type all
Set the below property in your global gradle.properties
file
android.enableBuildCache=true
Stop a running gradle build process
./gradlew -stop
Enable gradle to automatically download missing platforms in android sdk
Set the below property in your global gradle.properties
file
android.builder.sdkDownload=true
This is an experimental option and it only downloads build tools and platforms, but doesn't actually update Google or Support repository [Bug Ref]
Donot include both jcenter()
& mavenCentral()
in your build.gradle
file
JCenter is a superset of MavenCentral. [Ref tweet]
Clear your gradle cache if you think that bundled support and google play services lib in android sdk are inconsistent
~/.gradle/caches/
and delete everything inside the cache
folder.Setup handy adb
aliases for your terminal [Ref Link]
Append the below Aliases to your ~/.bashrc
or ~/.zshrc
file, save and restart the terminal. Once saved, use them as show in Usage column
Alias | Usage |
---|---|
alias screenshot="adb exec-out screencap -p > screen-$(date -j "+%s").png" |
screenshot |
alias startintent="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X shell am start $1" |
startintent https://twitter.com/nisrulz |
alias apkinstall="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X install -r $1" |
apkinstall ~/Desktop/DemoApp.apk |
alias rmapp="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X uninstall $1" |
rmapp com.example.demoapp |
alias clearapp="adb devices | tail -n +2 | cut -sf 1 | xargs -I X adb -s X shell pm clear $1" |
clearapp com.example.demoapp |
Setup Android Studio to fail build if code contains //STOPSHIP
[Ref Link]
To enable the //STOPSHIP
lint check, in your build.gradle
android {
...
lintOptions {
abortOnError true
fatal 'StopShip'
}
}
If you have a //STOPSHIP
comment in your code, this will cause an error to be thrown when a release apk is generated.
You can turn on //STOPSHIP highlighting in Android Studio (isn't enabled by default) in
Preferences
>Editor
>Code Style
>Inspections
.Search for STOPSHIP to find the correct setting.
Use adb install -g
to grant all permissions listed in the manifest [More Info]
Use alfi
to find the gradle dependency statement for a library
Its basically the command line version of Gradle, Please which is a web hosted.
Run
alfi name_of_library
Copy the desired library
Paste in your build.gradle
Use dryrun
to test a library directly
Just Run
dryrun REMOTE_GIT_URL
Output unit tests directly to the console [Ref Link]
A small neat trick to see Android unit tests logging results as they happen in the terminal.
android {
...
testOptions.unitTests.all {
testLogging {
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
}
Make your builds faster by building offline [Ref Link]
The
--offline
flag tells gradle to always use dependency modules from the cache, regardless if they are due to be checked again. When running offline, gradle will never attempt to access the network to perform dependency resolution. If required modules are not present in the dependency cache, build execution will fail.
Assembling develop debug at full speed:
./gradlew assembleDevelopDebug --offline
Running your unit tests at full speed:
./gradlew test --offline
Use an abtracted Logger class
If you want to automatically initialize your library, use a Content Provider [Read how Firebase does it - Ref Link]
Reduce installed app size with "android:extractNativeLibs:false"
in <application>
[Ref Link]
This will essentially prevent the system from creating a second copy of the .so files and fix the System.loadLibrary call so it’s able to find and open native libs straight from the APK, no code changes on your part required.
Selectivily execute a specific method in Android Studio [Ref Link]
Did you get one of these Google Play Developer Policy Violation Emails? Worry not, generate a Privacy Policy for your android app [Ref ink]
Define a variable at build time
In your build.gradle
android{
defaultConfig {
...
buildConfigField "String", "SERVER_ENDPOINT", '"http://www.myendpoint.com"'
buildConfigField "int", "FOO", "52"
buildConfigField "boolean", "LOG", "false"
...
}
}
and then use it in code as BuildConfig.SERVER_ENDPOINT
, BuildConfig.FOO
,BuildConfig.LOG
Calculate the version code and version name in your build.gradle
manually, based of version values*
In your app's build.gradle
versionMajor = 0
versionMinor = 0
versionPatch = 0
versionBuild = 1
verCode = versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
verName = "${versionMajor}.${versionMinor}.${versionPatch}"
// Use
android{
defaultConfig {
...
versionCode verCode
versionName verName
...
}
}
Calculate the version code and version name in your build.gradle
automatically, based on git information*
Note: These functions go specifically inside the app's
build.gradle
and cannot be used withext
.
In your app's build.gradle
// Version code is calculated as the number of commits from last commit on master
def getVersionCode = { ->
try {
def code = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', 'HEAD', '--count'
standardOutput = code
}
return Integer.parseInt(code.toString().trim())
} catch (exception) {
return "1";
}
}
// Version name is Last Tag Name + No. of commits form last Tag + short git sha
def getVersionName = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags', '--dirty'
standardOutput = stdout
}
return stdout.toString().trim()
} catch (exception) {
return "0.0.0.1";
}
}
// Use
android{
defaultConfig {
...
versionCode getVersionCode()
versionName getVersionName()
...
}
}
Get the date of build as a variable*
In your app's build.gradle
// Get the date of build
def getDateOfBuild = { -> // ISO 8601 time format
return new Date().format("yyyy-MM-dd'T'HH:mm'Z'").toString().trim()
}
// then use it as a variable in BuildConfig
android{
defaultConfig {
...
buildConfigField "String", "DATE_OF_BUILD", "\"${getDateOfBuild()}\""
}
}
Get the Git SHA as a variable*
In your app's build.gradle
// Get the last Git Short Hash
def getGitHash = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
// then use it as a variable in BuildConfig
android{
defaultConfig {
...
buildConfigField "String", "GIT_SHA", "\"${getGitHash()}\""
}
}
Activity LifeCycle [Ref Link]
Tip about onSaveInstanceState()
onSaveInstanceState()
is called only when the OS decides to kill the Activity
instance. It will not be called when Activity is explicitly killed i.e User pressed back button or finish()
is called from code.
Motion
Typography
Icons
Ripples
When implementing Ripple Effect use ?attr/selectableItemBackground
instead of ?android:attr
(Ref)
When implementing Ripples contained within the view like Button, use (Ref)
android:background="?attr/selectableItemBackground"
When implementing Ripples that extend beyond the view's bounds like ImageView: (Ref)
?attr/selectableItemBackgroundBorderless
Other Points to Note
Checkout From Java to Kotlin
Cheatsheet when you come from Java to Kotlin. Very nice resource to compare the two languages.
Listen to podcasts
There are others too, but the above two are the popular ones, you can lookup more using tag android
on sites offering Podcast Services.
P.S : I use Player.fm to listen to these podcasts. They even have an Android Client, all for FREE.
Checkout Android Dialogs Short byte sized android interview videos with experts.
Checkout CodePath Android Cliffnotes
It is the central crowdsourced resource for complete and up-to-date practical Android developer guides for any topic.
Checkout new android libraries
Android Arsenal - Android developer portal with tools, libraries, and apps
Checkout android example apps
Follow on Twitter
Create a List on Twitter
Bite-sized Android development videos
Bookmark these sites for staying upto date
Use freely available mockable api points
Subscribe to newsletters to stay upto date
ADB/Fastboot Tools made available as a separate package by google, download latest version for
Some other awesome utility tools
Awesome android libraries
If you would like to contribute by translating this doc, please do so by sending a PR which follows the below points
README-language.md
i.e README-English.md
, README-Greek.md
, etc.This curated cheatsheet includes tips and tricks that I have been following in my workflow as well as those being suggested/followed by other android devs worldwide.I have tried to add direct links wherever I could remember, giving people due credit who have explained the concepts. If you think I have missed any, then either send a PR or open an issue and I will fix it asap.
If you found this cheatsheet helpful or you learned something today and want to thank me, consider buying me a cup of
☕️
Copyright 2016 Nishant Srivastava
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.