Is there any method to mark some place it code, which has to be improved? I seen it before somewhere but can not remember now. It blocks release build, and it is not TODO comment. What is it?
I've found. It is StopShip lint check.
Enable it in 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 (wasn't enabled by default for me) in Preferences > Editor > Code Style > Inspections. Search for STOPSHIP to find the correct setting.
Source: https://www.reddit.com/r/androiddev/comments/5c8b0a/i_know_android_studio_allows_you_to_make_custom/d9uhdzt/
I don't think there is a native way provided to do so.
You may however do something like this, by control a single boolean:
static boolean isDebug = false;
assert isDebug = true;
if (isDebug)
{
/* Do stuff only for debug builds */
}
We need to use BuildConfig.DEBUG
if (BuildConfig.DEBUG)
{
/* Do stuff only for debug builds */
}
Its the proper way for writing some code only for Debug and no need to use any variables to check for debug as BuildConfig.DEBUG its taken care by Android run system depending on your Build Config.
Related
Is there a way to check within my android application if it's being debugged, like a DEBUG flag or somthing? I want to print a special message when the application is being debugged.
You can use BuildConfig.DEBUG. This is a boolean value that will be true for a debug build, false otherwise:
if (BuildConfig.DEBUG) {
// do something with debug build
}
There are two ways to check if the apk is being debugged or not
1. BuildConfig.DEBUG:
if (BuildConfig.DEBUG) {
// do something with debug build
}
Note: If you are using the first one then make sure BuildConfig is imported from your project or your app.
2.ApplicationInfo.FLAG_DEBUGGABLE
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) {
//Debug APK
}
I'm looking for a way to temporarily suppress a lint error or to schedule an error after a particular date or condition.
Here's some context:
I have an android app that is translated to multiple languages and I have set it up so that lint fails with an error if there are missing translations. Evidently this is done so that untranslated strings don't escape into the wild.
Whenever there's a new string resource, it takes a while until it gets translated, during which lint fails.
This can be suppressed or the strings can be marked as untranslatable but that beats the purpose of having the check in the first place.
Aside from that context, there are plenty more instances when a particular setting is "temporary". I don't like having to remember to flip back every switch.
The builds are on a CI server, releases are often and this happens in a team where anyone is able to "temporarily" ignore warnings.
Is there an automagical way to make sure things don't get ignored upon release?
Update:
Since asking this question, someone has developed a library that does just what I asked and more: https://github.com/Stuie/papercut
I don't know how you determin when it is time to de/activate lint. But maybe this helps:
You can switch Lint on/off with a boolean in the gradle script:
android {
lintOptions {
if (lintOn){
checkReleaseBuilds true
abortOnError true
} else {
checkReleaseBuilds false
abortOnError false
}
}
}
Add lintOn=false to your gradle.properties, otherwise gradle won't recognize it as variable.
Now you cann add a task and make it run before the build task:
task preBuild << {
// do stuff to determin if lint should run
lintOn = true
}
build.dependsOn preBuild
In this preBuild task you can now implement some code to check if you should run lint or not.
Here are some good examples of what a task can do.
I've created an application in android in release mode.
I want to remove all the logs in my project when i'm publishing my app in release mode.
how can i do it without duplicating my code?
can i remove the log using Gradle ?
You can make use of BuildConfig.DEBUG variable, which will be true for debug builds and false otherwise.
You could have a Constants file with a variable like
public static final LOG_ENABLED = BuildConfig.DEBUG;
then check the variable before you print a log.
if(Constants.LOG_ENABLED){
// print Log
}
Background
I've recently migrated my app to Android-Studio. I had some issues doing so, but I got over them eventually.
The problem
For some reason, on Android Studio, when I try to sign an APK, I get a lot of errors that look like this:
Error:(16) Error: "..." is not translated in "de" (German), "el" (Greek), "iw" (Hebrew) [MissingTranslation]
(where "..." is a string)
At the bottom, after a lot of errors of this kind, I see this:
Error:Execution failed for task ':app:lintVitalRelease'.
> Lint found fatal errors while assembling a release target.
To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
...
The question
I'm not sure what's wrong and how I can fix it. On Eclipse I did it very easily. Missing translations shouldn't stop me from signing an APK...
To me it seems as if Lint is preventing the exporting of the APK, and that the reason is that I didn't translate all of the strings. Is that true?
Can anyone please help me? How can I fix this, so that Lint will show me just warnings instead? or a confirmation dialog if I'm sure I want to do it?
The cleanest way to solve the problem is to disable Lint checks of missing translations for release builds only.
To do so add "disable 'MissingTranslation'" to your build.gradle file as shown below:
android {
buildTypes {
release {
lintOptions {
disable 'MissingTranslation'
}
}
}
}
To me it seems as if Lint is preventing the exporting of the APK, and
that the reason is that I didn't translate all of the strings. Is that
true?
Yes. Default option is lintOptions.abortOnError = true
Can anyone please help me?
You should open the build.gradle file located at the main project module, or the generic folder if you do not have a module. Then add the suggested lines:
android {
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
Some Lint warnings are by default turned to studio as errors, I don't actually know why, but in terms of translations I guess that is a way to "stop" you publishing an app that the translation is incomplete due to a last minute additions of some texts.
With the lintOptions checkReleaseBuilds abortOnError you set the checking of Lint not to run for release versions and also not stopping if an "error" is found. Below I explain where the Lint errors settings can be found, so if you want to go further you can go one step forward and read them one by one. Some of them provide helpful instructions for code optimizations.
How can I fix this, so that Lint will show me just warnings instead?
or a confirmation dialog if I'm sure I want to do it?
There is also an option at the Android Studio settings to change any Lint error to Lint warning, but I never test that. I usually turn to the gradle solution.
The option is located at Settings > Inspections > Android Lint. For easy find open Settings and at the search (located at the top) type Lint translation there you can change the translation options appear at the left from errors to warnings.
An other option if your error strings never going to be translated is to add at your XML string files tools:ignore="MissingTranslation" either at the root item or at each non-translatable string.
Simple way to solve this Error
Just add following Code To do add "disable 'MissingTranslation'" to your build.gradle file as shown below:
...
android {
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
...
OR You can also Add this:
android {
buildTypes {
release {
lintOptions {
disable 'MissingTranslation'
}
}
}
}
You could try to open "Translations Editor" and set the string "..." as "Unstranlatable".
You also must remove all translations of this string.
FWIW: If you don't plan on supporting other languages, then you don't need to disable the lint checks at all. Sometimes your project setup (or a library you're importing) may have accidentally - or intentionally - included a config to support additional languages by declaring a values- folder for that language like this for instance:
<your project source folder>/main/res/values-ar
This was the case for me so I simply removed the folder. But if you have no control over the offending library then one choice is to disable lint abortOnError as indicated in the accepted answer, or find a way to exclude 'library-imported' folders somehow. For the latter option you can start here
there is many solution but i tried
<string name="hello" translatable="false">hello</string>
It's the ignore attribute of the tools namespace in your strings file, as follows:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingTranslation" >
<!-- your strings here; no need now for the translatable attribute -->
</resources>
and from the Gradle
release {
lintOptions {
disable 'MissingTranslation'
}
}
and
android {
lintOptions {
disable 'MissingTranslation'
}
}
Working
buildTypes {
release {
lintOptions {
checkReleaseBuilds false
abortOnError false
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
In the newest version of ADT (r17) a generated constant was added BuildConfig.DEBUG that is set according to the build type. The problem I have is that it is never set to false, I expected it to change when doing "Android Tools -> Export Signed Application Package" but it hasn't for me.
So how do I change the build type?
Added a feature that allows you to run some code only in debug mode.
Builds now generate a class called BuildConfig containing a DEBUG
constant that is automatically set according to your build type. You
can check the (BuildConfig.DEBUG) constant in your code to run
debug-only functions
Currently you can get the correct behavior by disabling "Build Automatically", cleaning the project and then export via "Android Tools -> Export Signed Application Package". When you run the application BuildConfig.DEBUG should be false.
With Eclipse, I always disable "Build Automatically" option before Exporting the app in release. Then I clean the project and export. Otherwise it starts compiling in debug mode, and then the value of BuildConfig.DEBUG may be wrong.
With Android Studio, I simply add my own custom variable in the build.gradle:
buildTypes {
debug {
buildConfigField "Boolean", "DEBUG_MODE", "true"
}
release {
buildConfigField "Boolean", "DEBUG_MODE", "false"
}
}
When I build the project, the BuildConfig.java is generated as follows:
public final class BuildConfig {
// Fields from build type: debug
public static final Boolean DEBUG_MODE = true;
}
Then in my code I can use:
if (BuildConfig.DEBUG_MODE) {
// do something
}
I recommand to clean after switching debug/release build.
It doesn't work properly:
Issue 27940: BuildConfig.DEBUG is "true" for exported application package
It's disappointing that they sometimes release buggy features.
Check for imports, sometimes BuildConfig is imported from any class of library unintentionally. For example:
import io.fabric.sdk.android.BuildConfig;
In this case BuildConfig.DEBUG will always return false;
import com.yourpackagename.BuildConfig;
In this case BuildConfig.DEBUG will return your real build variant.
p.s I just copy this one from my answer here:BuildConfig.DEBUG always false when building library projects with gradle
It does work, but note that the code file never changes, even when exporting the signed file. The export process changes the value of this variable to false, which might give you the false impression that it is not working.
I tested this with logging statements like
if (com.mypackage.BuildConfig.DEBUG)
Log.d(TAG, location.getProvider() + " location changed");
When testing, my Log statements no longer produce any output.
From Preparing for Release:
Turn off logging and debugging
Make sure you deactivate logging and disable the debugging option
before you build your application for release. You can deactivate
logging by removing calls to Log methods in your source files. You can
disable debugging by removing the android:debuggable attribute from
the tag in your manifest file, or by setting the
android:debuggable attribute to false in your manifest file. Also,
remove any log files or static test files that were created in your
project.
Also, you should remove all Debug tracing calls that you added to your
code, such as startMethodTracing() and stopMethodTracing() method
calls.
More information is following the link.
The solution for me:
Project -> Build Automatically
Project -> Clean
Project -> Build
Project Export Android application
It's work in r20
I would want to propose a simple workaround if you use proguard during APK export.
Proguard provides a way to remove calls to specific functions in release mode. Any calls for debugging logs can be removed with following setting in proguard-project.txt.
# Remove debug logs
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
}
And optimization setting in project.properties.
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
With this, you don't need to concern any unnecessary String computation passing to debug log to which #Jeremyfa pointed. The computations are just removed in release build.
So the workaround for BuildConfig.DEBUG uses the same feature of proguard like following.
public class DebugConfig {
private static boolean debug = false;
static {
setDebug(); // This line will be removed by proguard in release.
}
private static void setDebug() {
debug = true;
}
public static boolean isDebug() {
return debug;
}
}
And following setting in proguard-project.txt.
-assumenosideeffects class com.neofect.rapael.client.DebugConfig {
private static *** setDebug();
}
I would prefer using this to disabling the Build Automatically option, because this doesn't depend on the builder's individual IDE setting but is maintained as committed file which are shared among developers.
Does not work properly as far as I understood (Android issue 22241)
I had some trouble on a project (working with Eclipse), that constant was not set to true when exporting a signed APK of my project :(
Would love to hear it works though
a good way is creating your own class :
public class Log {
public static void d(String message) {
if (BuildConfig.DEBUG)
android.util.Log.d(
"[" + (new Exception().getStackTrace()[1].getClassName()) + "]",
"{" + (new Exception().getStackTrace()[1].getMethodName()) + "} "
+ message
);
}
}
will you check your app level build.gradle debuggable true for release build
buildTypes {
release {
debuggable true
}
}
instead you keep false or comment that line
buildTypes {
release {
//debuggable true
}
}
now you will get BuildConfig.DEBUG false for release build
I've seen some strange behavior that has to do with when the values in BuildConfig are set to their final values. This may have something to do with your issue.
The simple explanation is that default values are set initially before Proguard is run, then after Proguard runs, the BuildConfig file is regenerated with the proper values. However, Proguard has already optimized your code by this point and you have issues.
Here is a bug I created against Gradle. https://code.google.com/p/android/issues/detail?id=182449