keystore When running or debugging your project from the IDE, Android Studio automatically signs your APK with a debug certificate generated by the Android SDK tools.
keystore Issues when using local debug keystore: - expiration date of 365 days - installing application from multiple computers require uninstalling first
keystore Issues when using local debug keystore: - expiration date of 365 days - installing application from multiple computers require uninstalling first - google services require keystore SHA-1 fingerprint
proguard On Android proguard is used for three things: - shrink unused code — helps you to survive the 64k limit - optimize code & APK - obfuscate code — makes your APK difficult to reverse engineer
proguard # rules-proguard.pro # Remove logs -assumenosideeffects class android.util.Log { public static boolean isLoggable(java.lang.String, int); public static int v(...); public static int i(...); public static int w(...); public static int d(...); public static int e(...); } # Proguard configurations for common Android libraries: # https://github.com/krschultz/android-proguard-snippets
strict mode Android StrictMode helps you to detect different kinds of problems: - closable object is not closed - file reading / network requests performed on main thread - uri exposed - ...
StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. java.lang.Throwable: Explicit termination method 'close' not called at dalvik.system.CloseGuard.open(CloseGuard.java:184) at android.database.CursorWindow.(CursorWindow.java:111) at android.database.clearOrCreateWindow(AbstractCursor.java:198) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197) at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237) at com.dd.template.MainActivity.onCreate(MainActivity.java:124) strict mode Example of log when you forgot to close SQLiteCursor:
StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. java.lang.Throwable: Explicit termination method 'close' not called at dalvik.system.CloseGuard.open(CloseGuard.java:184) at android.database.CursorWindow.(CursorWindow.java:111) at android.database.clearOrCreateWindow(AbstractCursor.java:198) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197) at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237) at com.dd.template.MainActivity.onCreate(MainActivity.java:124) strict mode Example of log when you forgot to close SQLiteCursor:
Version Name & Code Issues with usage of hard coded values for android versionName & versionCode. - you never know which commit represent specific version
Version Name & Code Issues with usage of hard coded values for android versionName & versionCode. - you never know which commit represent specific version - whenever you increment versionCode and change versionName you have to modify build.gradle file
Version Name For versionName we can use git describe command. a. The command finds the most recent tag that is reachable from a commit. b. If the tag points to the commit, then only the tag is shown. c. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit.
Version Name For versionName we can use git describe command. a. The command finds the most recent tag that is reachable from a commit. b. If the tag points to the commit, then only the tag is shown. c. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit.
Version Name For versionName we can use git describe command. a. The command finds the most recent tag that is reachable from a commit. b. If the tag points to the commit, then only the tag is shown. c. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit.
Version Name For versionName we can use git describe command. a. The command finds the most recent tag that is reachable from a commit. b. If the tag points to the commit, then only the tag is shown. c. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit.
Version Code For versionCode we can use total number of tags. Because every git tag indicate some version, versionCode for next version will be always greater than previous.
Static Code Analysis Tools Static code analysis tool - is source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth.
Lint >./gradlew lint Execution failed for task ':app:lint. Lint found errors in the project; aborting build. Wrote HTML report to: template/app/build/outputs/lint/lint.html
Lint # template/app/build/outputs/lint/lint.html ... Priority: 3 / 10 Category: Security Severity: Error Explanation: AllowBackup/FullBackupContent Problems. The allowBackup attribute determines if an application's data can be backed up and restored. It is documented at http://developer.android.com/reference/android/R.attr.html#allowBackup ...
Findbugs >./gradlew findbugs Execution failed for task ':app:findbugs'. FindBugs rule violations were found. See the report at: template/app/build/outputs/findbugs/findbugs.html
Findbugs # template/app/build/outputs/findbugs/findbugs.html ... SF_SWITCH_NO_DEFAULT Switch statement found in MainActivity.someMethod(int) where one case falls through to the next case SF_SWITCH_FALLTHROUGH Switch statement found in MainActivity.someMethod(int) where default case is missing ...
PMD # MainActivity.class ... private void someMethod(int a, int b, int c, int d) { if (a > b) { if (b > c) { if (c > d) { if (d > a) { // some logic } } } } }
Code Coverage Code coverage basically tests how much of your code is covered under tests. So, if you have 90% code coverage than it means there is 10% of code that is not covered under tests.
Continuous Integration Continuous Integration (CI) is the process of automating the build and testing of code every time a team member commits changes to version control.
Continuous Integration Continuous Integration (CI) is the process of automating the build and testing of code every time a team member commits changes to version control.
GitHub repository setup Webhooks allow external services to be notified when certain events happen within your repository. (push, pull-request, etc.) Protect branches to disable force pushing, prevent branches from being deleted, and optionally require status checks before merging.
Resources www.github.com/dmytrodanylyk/template www.pmd.sourceforge.net/integrations.html www.findbugs.sourceforge.net www.developer.android.com/studio/write/lint.html www.guardsquare.com/en/proguard www.bitrise.io - sample project - pmd official site - findbugs official site - lint user guide - proguard official site - continuous integration