The Layout Editor has a "configuration chooser" area above the layout editor, where you can choose screen size, orientation, etc:
It works just fine, but has some disadvantages:
It takes up a lot of space
Switching orientations requires multiple clicks
It's showing some settings that are rarely used
It does not handle narrow widths well; take a look at what happens to the menus on the second row for example:
In ADT 20, the old configuration chooser has been replaced by a brand new configuration toolbar:
Instead of combo boxes, it uses drop down menus, which allows us to use icons, separators and perhaps more importantly, we can lazily compute the contents of the menus.
Here's the locale menu for example, showing the usefulness of icons in these menus:
And here's the theme menu. As you can see we now have logical nesting and grouping, so unlike in the old drop down menu you don't have to scroll to find for example Holo.Light.Dialog. And all the themes local to the project, and any themes referenced explicitly in the manifest, are also grouped together:
Right to the left of the welcome menu is the orientation menu. You can just click on it to quickly flip orientation, so in the above screenshot the layout is currently in landscape orientation, and the flip button shows the portrait mode. You can also click on the drop down arrow next to the button, to see the other associated options:
Notice how the UI Mode and the Night mode have been moved into this menu; they aren't used often enough that they warrant permanent visibility in the layout editor.
And instead, we've added a new menu: The Activity chooser. This lets you choose the activity context to use for this layout:
When you open a layout the first time, we attempt to guess the right layout (by looking at your activity classes and seeing which layouts they reference), but you can choose a different activity here. The activity associated with a layout is used to pick which theme to render with, in the case where you've assigned themes to activities in your manifest file. You can also open the activity in the Java editor by choosing "Open activity name". In the future we will also use the activity<->layout association to drive other features.
The leftmost menu lists the current configuration, such as "default", or "layout-xlarge", etc. If you open the associated menu, you can see which other versions of this layout you have:
You can also create a new layout (which is what the "Create..." button in the old configuration chooser did).
The device menu to its right should be obvious; it's where you choose among the various screen sizes to render your layout with. We plan to add your AVD's into this menu as soon as possible.
And finally, the Android logo on the right is where you pick the rendering target for your layout. Instead of showing the version name (e.g. Android 4.0), we now show just the API number, though in the drop down menu you can see the full labels:
While the goal of the new configuration toolbar is to fit in a single line (which is why we abbreviate your screen names, the rendering target name, strip the "Theme." prefix off of theme names etc), in the case where it just won't fit, the toolbar will wrap:
We'll have a Preview 2 of ADT 20 out soon. Please give the new configuration toolbar a try and let us know if you see any problems.
posted Apr 17, 2012 3:24 PM by Tor Norbye
[
updated Apr 17, 2012 3:26 PM
]
In ADT 20 we're replacing the property sheet in the layout editor with a much better one (based on the WindowBuilder codebase):
There are several things to note here:
Important attributes are highlighted in bold
Values which have been edited for this widget are shown in blue.
Some default values are shown. For example, in this case the Text Color Link is not defined, but the default value is apparently (for this theme) @android:color/holo_blue_light, and a preview of that color is rendered.
Attributes can be nested; for example, the layout parameters are all nested in a single layout parameters section. All attributes from each defining class (such as TextView) are grouped together. You can use the Collapse All and Expand All buttons in the toolbar to quickly collapse/expand these categories.
You can switch to alphabetical sorting instead, if you know you want a particular attribute by name.
Advanced properties are hidden by default, and can be shown if you toggle the show advanced button:
In the above screenshot all the attributes with gray italics labels are advanced attributes which were hidden before we toggled the show advanced button (the leftmost button in the toolbar above). Notice also how it's rendering previews of not just colors, but drawable icons as well; the above shows the default text selection handles on an EditText.
There is improved support for entering values. Boolean values have a tri-state checkbox (on, off, default). The "..." button continues to open the resource chooser, but if you click into a value text field to edit it, you get completion support as you're typing. For example, when you're entering a resource value, it shows the possible completions:
And if you're entering an enum or flag, you get completion on the possible values:
You can also enter multiple flags:
NOTE: The new property sheet works best as a tall window, but the default Eclipse property sheet viewer is a wide window in the bottom area. We're working on a scheme to deal with this, but in the meantime, you may want to simply drag the property sheet window and dock it on the right, either sharing a tab with the outline window, or perhaps better yet docking it below the outline window.
First, there's a dropdown toolbar action which lets you run lint on the selected project, or on all projects, and clear markers:
Second, the lint window itself is no longer a long list; it's a hierarchical table, where each top level item represents a unique issue type. This makes it easy to scan through your project to see what kinds of issues lint found, without having to scroll through 200 unused resource warnings for example:
By default all the issue types are collapsed; here I've manually expanded the last issue type. You can quickly expand or collapse all items using the + or - buttons in the lint window's toolbar:
The other options in this toolbar include
Refresh, which re-runs the current analysis on the same projects
Fix, which automatically fixes the issue (this applies to issues where a quickfix is available)
Suppress this issue with an attribute or annotation
Ignore in this file (saves suppress information in lint.xml)
Ignore in this project (ditto)
Always ignore
Delete this lint marker
Delete all lint markers
Expand, Collapse
Configure Columns
Edit Options
Configure Columns lets you edit which columns are visible. There are several new columns you can display, such as Category, Priority, etc, and you can click on column headers to sort the display by the given column. There's also a new "Location" column, shown by default, which incorporates several different pieces of information: the file name, the line number, the parent folder name (useful when looking at translation or configuration issues), and the project name:
The Edit Options actions brings up the Lint Preference dialog, which has also been improved. You can now search through the options by filter:
such as
The options also let you enable all, disable all and restore to default which lets you quickly check just a single issue for example.
Finally, there are many new quickfixes for various issues, such as UseCompoundDrawable.
posted Mar 14, 2012 2:55 PM by Tor Norbye
[
updated Mar 14, 2012 3:17 PM
]
ADT 17 adds around many new checks, looking for bugs, performance problems, security errors, usability issues, etc. We've already described the API Check and some of the new performance checks.
Here's a brief summary of the others:
Find invalid @id references (where for example a RelativeLayout references an id that does not exist anywhere). If no match is found, it looks for spelling mistakes and suggests other similar ids in the error message.
Find incorrect casts in Java code where the cast is incompatible with the view type declared in XML layouts.
Find calls to setColor methods which pass the resource id for the color (R.color.blue) instead of a resolved color (getResources().getColor(R.color.blue)).
Find errors in format strings. This includes inconsistencies between translated versions, as well as incompatible types declared in XML and supplied in the String.format call in Java.
Check for deprecated XML attributes
Finds activities, services and content providers that are present in the code but not registered in the manifest
Finds onClick attribute references that do not correspond to an existing method handler
Find typos in XML namespace declarations, as well as unused custom namespace declarations, and ensure that custom namespaces in library projects use the new auto-namespace.
Find manifest files which declare more than one <uses-sdk>elements, or which fail to declare minSdkVersion or targetSdkVersion
Check dialog button order such that OK/Cancel are in the right order (depending on the target version of Android), that they are using the standard case ("OK", not "Ok" or "ok" etc), and that there aren't any Back buttons.
Check menus to ensure that they are using "ifRoom" instead of "always" for the showAsAction attribute (unless it's used sparingly)
Find hardcoded android:debuggable attributes on <application> elements. This can lead to accidentally leaving debug information in published applications.
Find hardcoded references to "/sdcard" in Java code; these should be using Environment.getExternalStorageDirectory().getPath() instead
Find "import android.R" statements in Java code, which can lead to confusing compilation error messages
Find Java code which creates world-writeable files (which can lead to security problems)
Find references to private resources (which can lead to runtime errors on devices that do not provide the resource, since private resources may disappear any time, and may not be present on all platforms.)
Finds method calls to java.lang.Math where a float variable is cast to a double and/or the return value is cast to a float, and suggests replacing it with the equivalent android.util.FloatMath method.
Finds calls to a getter on the same class where a field could be accessed instead.
Find XML files using a different encoding format than UTF-8, since this can lead to subtle bugs (and lint was fixed to properly use the specified encoding)
Find XML resource files that contain text which should not be there (such as in layouts). This can identify accidentally malformed documents which happen to be valid XML, such as a missing "<" tag opening character.
Find style references which lead to cycles, such as extending self.
Check for usages of edit-centric attributes on a <TextView>
posted Mar 9, 2012 2:35 PM by Xavier Ducrohet
[
updated Mar 28, 2012 1:22 PM
]
In revision 17 of the Android SDK Tools and of the Eclipse ADT plug-in, we have made a lot of improvements to the dependency management of Android projects.
The first thing we changed was to align both the Ant-based build system and the Eclipse plug-in so that they behave the same.
Projects have source folders, as well as Library Project and jar file dependencies. With no other setup needed than adding Library Projects as a dependency in project.properties, a project’s classpath is automatically populated with:
The content of the project’s libs/*.jar
The output of the Library Projects.
The Library Projects’ libs/*.jar
These items, plus the output of the compilation of the project’s own source code, are sent to dex for bytecode conversion and inclusion in the final APK.
Because a project could depend on several libraries using the same jar files, the build system now looks at all the required jar files, detects duplicates coming from different libraries and removes them. This will prevent the dreaded “already added” error from dx. See below for how duplicates are found.
Important change: We have changed the way Library Projects generate and package R classes:
The R class is not packaged in the jar output of Library Projects anymore.
Library Project do not generate the R class for Library Projects they depend on. Only main application projects generates the Library R classes alongside their own.
This means that library projects cannot import the R class from another library project they depend on. This is not necessary anyway, as their own R class includes all the necessary resources. Note that app projects can still import the R classes from referenced Library Projects, but again, this is not needed as their own R classes include all the resources.
Eclipse specific changes
The dynamic classpath container called “Library Projects” has been renamed to “Android Dependencies” as it now contains more than just Library Projects.
The container will now also be populated with Java-only projects that are referenced by Library Projects. If those Java projects also reference other Java projects and/or jar files they will be added automatically (jar files referenced through user libraries are supported as well).
Important: this only happens if the references are set to be exported in the referencing project. Note that this is not the default when adding a project or jar file to a project build path. Library Projects (and the content of their libs/*.jar files) is always exported.
Important: If you are still referencing jar libraries manually instead of putting them under libs/ be aware of the following:
If the project is a Library project, these jar libraries will not be automatically visible to application projects. You should really move these to libs/
If the project is an application, this can work but you must make sure to mark the jar files as exported.
Here's how to mark Java project and jar libraries as exported (the Android Dependencies container does not have to be marked as exported, it is always exported anyway):
Again, duplicates (both projects and jar files) are detected and removed.
Dependency resolution
When a project references two Library projects that both require the same jar file, the build system has to detect and resolve the duplication.
A full dependency system would associate each jar file with a fully qualified name and a version number to figure out which version to use.
Unfortunately the Android build system does not have a full dependency resolution system (yet). In the meantime we have implemented a very basic system that follows these rules:
Jar file are identified strictly by their file names.
This means mylib.jar is different than mylib-v2.jar and both will be packaged, possibly resulting in “already added” dx error if they are actually the same library in a different revision.
For jars with the same file name, “same version” means same exact file.
Currently our detection is very basic, checking only that the files are identical in size and sha1.
If two libraries each include in their libs folder a file called mylib.jar but these two files are different, then the build system will fail indicating a dependency error.
The solution is to make sure the two jar files are actually the same one if they are the same library or to rename them if they are different libraries.
Special case for android-support-v4.jar and android-support-v13.jar.
We make a special case for these two libraries because -v13 contains a full version of -v4 inside. If both are found, then only -v13 will be used.
Note that we can’t guarantee that the version of -v4 inside -v13 is the same as version used by the other libraries. We recommend that when you update your project with a newer version of the support library, you update all of your projects at the same time, whether they use -v4 or -v13.
posted Feb 27, 2012 4:08 PM by Tor Norbye
[
updated Feb 27, 2012 4:21 PM
]
ADT 17 brings a number of improvements to the ProGuard integration.
First, we've updated the bundled version from 4.4 to 4.7. Along with a number of other fixes and enhancements (see the ProGuard documentation at http://proguard.sourceforge.net/), this fixes the dreaded "Conversion to Dalvik format failed with error 1" error some users have experienced. We've also updated the code which launches ProGuard, which should hopefully address a number of "spaces in paths" issues.
Second, we've changed the way configuration files are handled.
In previous releases, when you created a new Android project in ADT, we would copy a default "proguard.cfg" file into your project. This file contained a number of rules necessary for using ProGuard with Android, such as disabling certain optimizations not compatible with Android, adding "keep" rules to prevent shrinking methods only referenced from XML, etc.
However, over time, we've both discovered bugs in the default configuration, and of course as the Android API keeps evolving new additions to the rules are necessary as well. The problem we've run into is that users now have stale copies of the old proguard.cfg file in their projects. We've added some lint rules to detect some known bad patterns -- however, when users start editing and reorganizing their own proguard configuration files it gets very difficult to determine if a file is "up to date" with respect to the current recommendations.
Furthermore, most users don't want to read the ProGuard documentation and tweak the configuration -- they just want to get their applications shrunk and obfuscated before uploading it to the Market.
Therefore, as of ADT 17 we've split the configuration file in two halves:
A "default" set of rules for Android
Project-specific flags
The critical point is that the default set of rules is no longer copied into the project. It resides in the tools install (specifically tools/proguard/proguard-android.txt), and gets updated along with the rest of the tools.
The project specific flags are any local additions to the ProGuard configuration, such as specific -keep flags you want to add that are specific to your own code. By default, this file is named proguard-project.txt in the root of your project. We switched the file extension from .cfg to .txt since these are really just text files, and by changing the file extension you can just double click on the files in Eclipse and edit the files. (With .cfg, or the .pro extension used in the ProGuard documentation, Eclipse would open a native editor, which often would be unrelated to ProGuard; in my environment .pro files opened in an editor for editing Prolog files.)
Note that this behavior is not mandatory. You can continue to completely specify the complete ProGuard configuration in your project.
To make this all work, we've changed the meaning of the proguard.config property in your project.properties file. In older versions, the way you would enable ProGuard shrinking and obfuscation was to define proguard.config=<path to config file, usually just proguard.cfg>.
As of ADT 17, the proguard.config property refers to a path instead, so you can specify as many configuration files as you want. These are all joined together by ProGuard. By default, ProGuard is turned off, but the project.properties files for new projects contain the following comment block:
# To enable ProGuard to shrink and obfuscate your code, uncomment this
(You can use ${sdk.dir} and ${user.home} in these paths to avoid putting absolute paths in your project file, which is particularly important since this project.properties file typically is checked into version control.)
So, to enable ProGuard in the default way, simply uncomment the above line. You'll pick up all the default Android ProGuard configuration flags from the tools directory, and when we update the tools to fix bugs or update the configuration based on Android changes, you'll automatically be using them.
If you want to completely control your ProGuard configuration, simply specify just your own configuration file instead. Note that ProGuard typically doesn't let you subtract flags, so if you disagree with one of the default flags, you'll need to copy the global configuration into your own files and remove the lines you want to disable. One such flag you might want to consider is the -dontoptimize flag. The main reason developers use ProGuard is for the shrinking and obfuscation aspects (to make downloads and runtime sizes smaller, and to keep the code somewhat private, and there are performance benefits to symbols as well). Dalvik performs many of its own optimizations, and some of the optimizations performed by ProGuard are incompatible with Dalvik, so to avoid hard-to-figure-out bugs (and because the net performance gain is usually small), the default configuration turns off optimization. If you want this, look at the commented out optimization flags in the default file, copy the configuration to a local file and remember to test carefully. And also make sure that you regularly check that your local configuration is up to date.
The default configuration file in ADT 17 has been updated a fair bit, so if you're not going to be using it directly, you might want to compare your own copy with the new copy to see if you're missing anything. We've added some more comments to explain the various flags.
Now, everything explained above refers to new projects created from this point forward. What about existing projects?
Don't worry, we don't touch them. Everything continues to work just as it does today; none of your flags are changed automatically. However, we suspect that most developers are not using a deliberate configuration, they're just using what they got when they created their project, and they might not be aware that their configuration is out of date. To help users become aware of this whole issue, we've added a new lint rule to detect this scenario:
Hopefully this will contain enough information to make it obvious how to edit your project.properties files to link to the default Android configuration file and any remaining local flags. This lint rule only kicks in if you've actually enabled ProGuard, such that it won't bother all the developers who have a default proguard.cfg file in their project because it was created for them, but where it is not being used.
Finally, note that the proguard.config property is a path. You can specify more than just these two files. If you want, you can also use the ${user.home} flag to reference to your home directory. Thus, you can have the "global" Android defaults in ${sdk.dir} as shown above, and your own "per-user" flags (shared between all your projects) in ${user.home}, and finally any flags that really are project specific in the project using just a project relative path.
posted Feb 23, 2012 4:01 PM by Tor Norbye
[
updated Feb 23, 2012 4:20 PM
]
Some of the new lint checks in ADT 17 are aimed at finding performance issues.
The DrawAllocation detector finds cases where you are allocating new objects during a paint, layout or measure method (and you're not doing it just once via lazy initialization). The recommended way to do this is to preallocate any objects you need during a drawing operation, or to initialize them lazily and reuse for each paint. If not, you'll be generating a lot of garbage which can lead to UI lags.
In ADT 17 the HTML report has been revamped a bit. Here's what you see for a couple of DrawAllocation errors:
Another useful check locates cases where you're using the general HashMap class with an Integer key. Android has several optimized classes for this scenario (SparseIntArray, SparseBooleanArray, SparseArray) which you're better off using:
In a similar vein, there's a new detector which finds usages of various Math functions, such as Math.sin(). If it sees that you are converting a float to a double in order to call the function, or converting the result back from a double to a float (even if it's done implicitly - no need to have explicit casts since this detector is operating at the bytecode level), then it will suggest that you replace your call with the corresponding android.util.FloatMath method instead:
In Android 4.0, the Data Usage feature in Settings enables long-term monitoring of how an application uses network resources. Starting with Android 4.0.3 and the upcoming DDMS r17, you can watch how an application uses network resources in real-time. You can also distinguish between different traffic types by applying a “tag” to network sockets before use. These tags are shown in a stack area chart in DDMS, as shown below:
In code, you can set tags on a per-thread basis with TrafficStats.setThreadStatsTag(), then manually tag sockets using TrafficStats.tagSocket() and untagSocket(). Alternatively, the Apache HttpClient and URLConnection libraries included in the platform will automatically tag sockets internally based on the current getThreadStatsTag() value. (These libraries correctly tag/untag sockets when recycled through keep-alive pools.) Here’s a typical example:
TrafficStats.setThreadStatsTag(0xF00D); try { // make network request using HttpClient.execute() } finally { TrafficStats.clearThreadStatsTag(); }
Socket tagging is supported in Android 4.0, but displaying real-time stats is only available for devices running Android 4.0.3 or higher.
In addition to adding a lot of new lint checks, the new version of Lint in Tools 17 adds improved support for ignoring issues that you have manually verified and want to suppress.
The easiest way to do it is probably via the Lint toolbar window:
These buttons let you (from right to left) :
Disable the specific issue check completely
Disable the specific issue in this project
Disable the specific issue in this file
Disable this specific issue by adding a suppress annotation or attribute
If you disable an issue in a project or file, this gets recorded in a special file named lint.xml in the project root directory. You can check this file into version control and share it with the rest of your team. For more details on this, see the Suppressing Lint Warnings document. This facility works in Tools 16. The remainder of this blog post deals with the new suppress support coming in Tools 17.
The first button lets you ignore a specific issue encountered in a Java or XML file.
If the error is in a Java file, it adds a @SuppressLint annotation. In addition to the button in the lint view, you can also do this directly while editing Java files by just invoking Quick Fix when the cursor is on a line containing a lint warning:
As you can see, this offers to add the @SuppressLint annotation in three different places: the surrounding method and class contexts. The annotation will suppress any lint warnings of the given type for the scope that the annotation is annotating. (For this specific issue, "NewApi", there is an additional available annotation, @TargetApi, so the quickfix offers it. See the Lint API Check blog entry for details.)
The annotation takes a String parameter which lists the id of the issue to suppress. While the quickfix automatically supplies it, if you are editing manually you can also find the id listed at the end of each lint error message in the command line output as well as in the HTML reports.
To suppress more than one issue, supply a String array like this:
@SuppressLint({"NewApi","StringFormatInvalid"})
and you can also use @SuppressLint("all") to suppress everything. (The new annotations is provided in the new annotations.jar file which ships with Tools 17).
In XML files, you can use the new tools:ignore attribute in a similar way to suppress errors (see the third quickfix in the list which offers the suppress attribute):
This will modify the code as follows:
If necessary, it adds the namespace xmlns:tools="http://schemas.android.com/tools"
If adds the attribute tools:ignore="HardcodedText" on the given element.
Just as with Java annotations, this attribute is inherited, so you can specify it on the root of an XML document to suppress all warnings of the given type within the document. And just like the annotation, you can supply a comma separated list of issues (or "all") to suppress the given list of issues.
Note that the new tools namespace is special. AAPT in Tools 17 will deliberately skip these attributes, so they do not end up in the compiled XML shipped with your application, so there is no cost at runtime.