Android Studio (using SDK 19, 21 or 22) shows an error that Eclipse ADT (using SDK 19) does not:
Error:9-patch image D:\Workspaces....\res\drawable-hdpi\btn_bg_common_press.9.png malformed. Error:Frame pixels must be either solid or transparent (not intermediate alphas). - Found at pixel #4 along top edge.
Or another error:
Error:Ticks in transparent frame must be black or red.
both within aapt
Error:Error: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'E:\Android\sdk-Android-Studio\build-tools\19.1.0\aapt.exe'' finished with non-zero exit value 42
Example of file is above, but there are 20+ such files that worked well.
How do I make Android Studio or Gradle skip this error and not fail without having to modify those files one-by-one?
If it is not possible with Gradle, what command-line tool could I use to replace all transparent pixel with non-transparent?
The build.gradle file for the application module (where resources are) is below.
I have tried both with SDK 19 and SDK 21 and build tools 19.1, 21.1.2, 22.
A similar issue on AOSP, Issue 159464: Android studio: mergeDebugResources FAILED when importing Eclipse project.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.+'
}
}
allprojects {
repositories {
jcenter()
}
}
//---
task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
apply plugin: 'com.android.application'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':afinal')
compile 'com.android.support:appcompat-v7:19.0.+'
//compile 'com.android.support:appcompat-v7:21.0.+'
}
//---
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
compileSdkVersion 19
buildToolsVersion "19.1.0"
//compileSdkVersion 21
//buildToolsVersion "21.1.2"
//compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION)
//buildToolsVersion project.BUILD_TOOLS_VERSION
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
zipAlignEnabled true
//signingConfig signingConfigs.release
}
debug {
zipAlignEnabled true
}
}
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 // false also required by https://wiki.jenkins-ci.org/display/JENKINS/Android+Lint+Plugin
}
}//android
Android Gradle plugins sources are at https://android.googlesource.com/platform/tools/build/+/master.
How automatically solve the issue (without checking all images in different resolutions)
Not possible. Since you want the .png to behave like a nine-patch (expand along the edges, not stretch the whole bitmap), you're going to have to format them as such ergo you have to modify the files.
Proposed alternative
Since the shape is so simple you'd be better off deleting all variants of this file (saving space, time and headache in the process) and create /res/drawable/btn_bg_common_press.xml
drawable with following contents:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="16dp"/>
<solid android:color="#ccc"/>
<stroke
android:color="#0c0"
android:width="2dp"/>
</shape>
You can use dimen
and color
resources instead of hardcoded values. Additionally you might want to add the padding
element inside shape
<shape...>
<padding
android:top="8dp"
android:left="8dp"
android:bottom="8dp"
android:right="8dp"/>
</shape>
and/or wrap the shape
element inside an inset
element.
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="8dp"
android:insetLeft="8dp"
android:insetBottom="8dp"
android:insetRight="8dp">
<shape...>
</inset>
If you do that, the drawable will have implied padding and you won't have to set it when styling widgets. Since you have multiple state drawables for the button I suggest you convert all of them to XML to make sure the line thickness and corners match.
Despite the root element's name the <shape>
actually inflates to GradientDrawable
(meaning you can fill it with gradient instead of solid color). Review GradientDrawable
docs for all its options. Do not ever use ShapeDrawable
programmatically, it just doesn't work.
Analyzing 9-patches
Consider the three following enlarged images.
Candidate #1 is a nine-patch. It has reserved 1px on each side for stretch and padding specification. This one will behave as an ordinary bitmap when stretched. If the width will be greater than height, so will the border thickness on sides. The border will scale proportionally.
Candidate #2 is also a nine-patch and is actually saying it's going to stretch everything besides 1px border and will have implied padding of 3px on each side. It will have a nice crisp 1px border when stretched.
Candidate #3 is NOT a nine-patch. It scales the same way as #1.
Now let's take a look at enlarged version of the image you included in OP:
As you can see it's not a nine-patch, so it won't get interpreted as one and the build tools are kind enough to warn you of that. Even if older build tools were more forgiving and added transparent 1px on each side for you, the result would have behaved like an ordinary bitmap, meaning when stretched it would look like specimen A instead of expected result specimen B.
Here's more reading on nine-patches. This explains what the extra 1px on each side is used for.