Difference between setBackgroundDrawable() and setBackground() - java

I just upgraded my Android project's build target to API 17, and I'm now getting warnings about setBackgroundDrawable being deprecated. The answer appears to be to use setBackground, but that's not available in older versions.
Is there any actual advantage to using the new method, or did Google just want to change the name? I don't see any point in complicating my code with platform version checks or reflection if the two work the same.

Is there any actual advantage to using the new method, or did Google just want to change the name?
They seemed to only want to change the name, look at the source code:
public void setBackground(Drawable background) {
//noinspection deprecation
setBackgroundDrawable(background);
}
#Deprecated
public void setBackgroundDrawable(Drawable background) { ... }
All of the work is still done in setBackgroundDrawable(). For now, you can ignore the deprecation warnings but understand that in some future API setBackgroundDrawable() will be removed.
In case you are curious, setBackgroundResource(int resid) simply creates a drawable from the resource ID and calls setBackground() (which again calls setBackgroundDrawable())...

Related

Gradle javadoc hide specified method [duplicate]

I'm using javadocs generated by the javadoc Ant task to document a web service, and I want to exclude some constructors from the output. How do I do that?
There is no way to do this for public methods. The standard practice (even in quite a few JDK classes) is to indicate that the method or constructor is not meant for public use.
There is a plan to add an #exclude tag in the future:
#exclude - for API to be excluded from
generation by Javadoc. Programmer
would mark a class, interface,
constructor, method or field with
#exclude. Presence of tag would cause
API to be excluded from the generated
documentation. Text following tag
could explain reason for exclusion,
but would be ignored by Javadoc.
(Formerly proposed as #hide, but the
term "hide" is more appropriate for
run-time dynamic show/hide
capability.) For more discussion, see:
Feature Request #4058216 in Developer
Connection.
Isn't excluding something public from your documentation just a variation on "security through obscurity" (or rather, "documentation through obscurity")? If the constructor is part of your code's API, it's available for them to use. If they find out about it and use it, is that their fault (since you made it public in the first place)?
If you can change the constructor's visibility or remove it altogether, I would go for that. If you cannot remove it from the API, make it known in the Javadoc for the constructor that it's not intended for use via web service. That way you've established a contract with users of your API, informing them not to use it.
It's better to document that it should not be used instead of not documenting it at all (if it's public). Not documenting it adds risk that it gets inadvertently used, and then the client code using it breaks when you change the implementation.
See the relevant Javadoc FAQ entry.
There is currently no Javadoc option
to hide, exclude or suppress public
members from the javadoc-generated
documentation.
It would appear this is not possible in the vanilla Javadoc, but some workarounds are offered.
Currently the simplest solution is to start the javadoc comment with #deprecated, and then pass -nodeprecated to the javadoc command. Of course, this may not be acceptable if you have actual deprecated items which you nevertheless want to include in the documentation.
Change the method access level of the method, then use the use the javadoc task's access-level filtering attributes, private, package, etc. Only do this if it makes sense in your code, though, e.g., method that had inappropriately loose access levels.
For constructors, for example, you could reduce the access level to package, then create a factory class in the same package that provides construction access outside the package. The factory class can be easily filtered from the javadocs. Kind of hacky, but it works.
Give Chris Nokleberg's ExcludeDoclet a try:
http://www.sixlegs.com/blog/java/exclude-javadoc-tag.html
I've just been experimenting with it and it seems to do the trick.
The closes I got is to use Doclava, which has the #hide tag you can specify in method documentation.

Extending implementations for GWT JRE emulation

There are a couple of cases where I would like to add/modify just one method of GWT's implementation of a JRE class (see Class.isInstance or System.arraycopy, for example).
As GWT is improved, other methods in the same classes might be updated, so I would rather not just take the current implementation of the entire class, modify it, and then stick it in a super-source directory, as I would then have to check for significant changes in these files every time a new version of GWT is released.
I would much prefer to just extend the already existing GWT implementation and only override the one method I would like to change. Is that possible somehow?
This might help:
Deferred Binding Using Replacement
The first type of deferred binding uses replacement. Replacement means overriding the implementation of one java class with another that is determined at compile time. For example, this technique is used to conditionalize the implementation of some widgets, such as the PopupPanel. The use of for the PopupPanel class is shown in the previous section describing the deferred binding rules. The actual replacement rules are specified in Popup.gwt.xml, as shown below:
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDeferred.html

Why use reflection for HttpResponseCache?

In the documentation of HttpResponseCache there is a section:
Working With Earlier Releases
This class was added in Android 4.0 (Ice Cream Sandwich). Use
reflection to enable the response cache without impacting earlier
releases:
try {
File httpCacheDir = new File(context.getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
}
catch (Exception httpResponseCacheNotAvailable) {
}
You can see this call via reflection in a questions here on SO (e.g. here), and examples on the web. I also took over code that contains this exact snippet to set up the cache (including the comment, so its probably just copypasta). However, I don't quite understand why you have to use reflection here.
Normally when I want to use a method added at a certain API level above my defined minSdkVersion, I would use the following pattern:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// do something here
}
so why isn't this the default pattern for HttpResponseCache. What is the advantage of using reflection? It certainly doesn't add to the readability of my code. Does HttpResponseCache actually work below ICS when using reflection this way?
EDIT: I don't have an old Android device here and my emulator refuses to start at all, so I can't simply test it at the moment. Maybe it just crashes horribly without reflection.
What is the advantage of using reflection?
First, quoting the documentation:
This class was added in Android 4.0 (Ice Cream Sandwich).
By "was added", they mean "was added to the Android SDK", and by "Ice Cream Sandwich", they really mean Android 3.2 (API Level 13) based on the rest of the JavaDocs.
However, the HttpResponseCache class itself has existed in the framework for longer, hopefully since Android 1.0 given their recommendations. However, that class was marked with the #hide annotation, so it could not be used directly by apps until API Level 13.
Your Java version guard block using Build will avoid referencing this class directly on older devices. However, it does not actually configure the cache on older devices, either.
Their approach will work on all versions of Android and will allow you to configure the cache, as the class has existed since the beginning.
It is fairly rare that Google explicitly authorizes the use of reflection to get at hidden classes or methods this way, which is why you don't see it often in official documentation.
Unfortunately your suggestion will not work for older versions. Think about the following. They added method install(File, long) to new version. But the code that calls this method is packaged into other jar.
Now you have old version of jar that contains HttpResponseCache and new version of jar that calls it. If you write there
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
cache.install(file, number);
}
NoSuchMethodError will be thrown even if expression of if is false.
Using reflection is a ugly but useful technique to prevent this.

Java annotations for code style with semantics like #Deprecated

Does anybody have some kind of "code style" annotations in the project, ex: #OverEngineered for over-complexed code or #Duplicated... etc.
Ideally I'd subclass #Deprecated for that (#OverEngineered extends #Deprecated) to get the IDE highlight it, but java annotations are not inherited.
So I wonder if there is some workaround to get the IDE to highlight such code-style custom annotations as deprecated? Or is this the wrong way or wrong task in general?
You could write a family of these annotations, and then use them alongside #Deprecated. The latter gets you the warnings, the former supply the details to human readers. You could write a Checkstyle rule to require that every deprecated thing has an explanatory annotation, and/or that every explanation accompanies a deprecation.
Rather than writing several annotations, though, i'd write one, which takes an explanatory label as a parameter. I'd call it #BecauseItIs. So:
#Deprecated #BecauseItIs("overengineered")
public void calculateSumOfTwoIntegersUsingSurfaceIntegrals(int a, int b) {
The workaround would be implemented with a plugin you develop for Eclipse. I would say, however, nothing is more semantically as a good written comment in the code.
After all it depends on the purpose. But I think a good comment is better than a plugin which anyone has to install.
It's not clear to me if you have another goal besides calling attention to the spot in the IDE. You mention #Deprecated which also shows up in the Javadoc, IDE documentation popups, and compiler output.
For simply the IDE highlighting without the other possibilities, you could leverage the FIXME / TODO sorts of comment tags that most IDEs support (at least those I've used). Just add your own tags for OVERENGINEERED: this is too ... etc.
Eclipse allows you to also specify if you want case matched, so it could be OverEngineered:

Which GWT EventBus should I use?

In the gwt-user.jar there are 2 EventBus interfaces and SimpleEventBus implmentations.
com.google.gwt.event.shared.EventBus and com.google.web.bindery.event.shared.EventBus
I'll refer to these as 'gwt.event' and 'web.bindery'.
Looking at the JavaDocs and source code I can see that the gwt.event merely wraps the web.bindery one. However the gwt.event implementation also hides a number of deprecated methods
So which implementation should I use? (I'm on GWT 2.4)
Generally you should use the one in com.google.web.bindery. The only version used to be in com.google.gwt.event, but when RequestFactory and AutoBeans were moved out of GWT itself and into com.google.web.bindery so they could work in non-GWT clients.
If you use the com.google.web.bindery version in your presenters and such, it will make it easier to use outside GWT apps, should you need to. You'll also not get deprecation warnings when passing that instance to PlaceController and other classes that use EventBus.
I know this question has already an answer but might be worth while adding the following. As I said in my comment above, Activity still needs the com.google.gwt.event.shared.EventBus class. To avoid deprecated warnings, I did the following (I use GIN):
public class GinClientModule extends AbstractGinModule {
#Override
protected void configure() {
bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
...
}
#Provides
#Singleton
public com.google.gwt.event.shared.EventBus adjustEventBus(
EventBus busBindery) {
return (com.google.gwt.event.shared.EventBus) busBindery;
}
...
By doing this, you will always be using the object from the "new" version of Event bus in the bindery package.
If you use Activities, then you'll probably have to use the deprecated one, at least until they clean up the whole API: http://code.google.com/p/google-web-toolkit/issues/detail?id=6653.
To make the choice even more complex. I am using guava in my GWT application and the google guys have added yet another EventBus in there (even less feature complete).
Maybe those guys need to sit together and define ONE implementation to rule them all ?
Obviously I would like to avoid all dependencies on GWT for code that is not strictly used in GWT code, so the Guava one looked interesting to me.

Categories