Android - redefining class removed from support library (AsyncTaskCompat) - java

Firstly, apologies if I have not included all the required info for this question to be answered. I am somewhat new to Android development and am still getting my head around the build tools, API levels etc. So please let me know if there is any additional info I should provide to help you help me!
After updating my Android project compile sdk version to 27, I realised that version 27.0.2 of com.android.support:support-v4 no longer includes AsyncTaskCompat (that class has been deprecated & removed).
I have a third party library that is not open source, not easily replaceable, is no longer supported and still uses AsyncTaskCompat.
Since AsyncTaskCompat is open source, I was thinking I could simply reintroduce it somehow by redefining it in my project.
I've tried redefining it under my project in com.android.support.v4.os but even though the project compiles without any issues, when I run the section of the app that uses the third party library I get a crash with a class not found error for AsyncTaskCompat.
Is there something obvious I might be missing?

No need to add a specific Android Library module.
Only add the classes bellow to your project using the package name "android.support.v4.os":
AsyncTaskCompat
AsyncTaskCompatHoneycomb

Answering my own question here after another day of hacking away.
It is in fact possible to re-implement these deprecated/removed classes in a way that the dependency will be able to use it.
The steps are described here in case anyone needs it in the future
Create a new Android Library module for your app
Reimplement the missing classes using the appropriate namespace
In my case I needed to reimplement android.support.v4.os.AsyncTaskCompat which is open sourced so all I had to do was copy the code from source.
Add the module as a dependency of your main app module.

Related

Is there a way to import a specific version of a java sdk in a project with multiple versions of the same sdk?

Because of, reasons, I cannot just update the old version of the aws sdk I'm working with, but I also need some new things that are in a more recent version.
The problem is that if put both version of the sdk the project I get a "java.lang.NoSuchMethodError" because I think it's trying to use the old version of the sdk. If I delete the old one and just use the updated one it works fine. Is there a way to keep both version of the sdk and tell my java class which one to exclusively import?
There are a couple of ways, but they're pretty nasty.
The arguably "more correct" approach is to could use a custom classloader - see this answer for details. However, that's not exactly simple, and can lead to weird outcomes.
A simpler, but somewhat nastier approach is to get the source code of both SDKs (if available), and rename the packages. For example if we have sdk_v1 and sdk_v2, we can rename the packages to com.example.sdk.v1 and com.example.sdk.v2,
Once there's no package name collision, there's no problem using two different SDKs, even in the same class - just use fully qualified imports (see answer):
com.example.sdk.v1.SomeClass.someFunc() will not collide with com.example.sdk.v2.SomeClass.someFunc()

intellij auto import custom buildfile

I dislike the build tools that exist for Java. So I wrote my own. But there is one feature that it doesn't have yet; auto-import of changes into the IntelliJ project.
I'm having trouble finding information on how to do this. Tutorials on how to write IntelliJ plugins throw tons of useless stuff at me (creating UI for example).
I know this isn't your typical stackoverflow I-have-a-bug question but I'm quite lost and could use a pointer in the right direction.
If you need to know when a certian file was changed and auto-import information from this file you can use VirtualFileManager.addVirtualFileListener().
Or even use fileDocumentManagerListener extension point. Whatever suits your needs more.
So far I've managed to create a simple IntelliJ plugin. The start is fairly simple. IntelliJ has the plugin project skeleton built in. File->new Project is enough there.
From there I've created a class that implements ModuleComponent. The documentation here (https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_components.html) says it will be loaded whenever a module is opened.
To get it to work I had to add this stuff in the plugin.xml:
<module-components>
<component>
<interface-class>packagename.ClassName</interface-class>
<implementation-class>packagename.ClassName</implementation-class>
</component>
</module-components>
The documentation manages to hide this next step but its possible to give the ModuleComponent a constructor like so:
public ClassName(final Module module) {}
This should give me an instance of the Module class to read values from and to modify the way I need.
As it turns out IntelliJ makes it difficult to figure out how to do things. There is no Javadoc for example. People seem to suggest reading the source code. Weird..
A quick look through the methods of Module didn't really help me much. Google let me know that in order to make changes to the Module I could do the following:
ModuleRootManager.getInstance(module).getModifiableModel()
I can call several methods on this model and finally call .commit() when I'm done to persist the changes. The ModifiableRootModel has two methods that look very promissing:
ModifiableRootModel.addModuleOrderEntry()
ModifiableRootModel.addLibraryEntry()
The first takes a Module instance. I'm hoping that if I add the correct Module this will allow me to well, add modules :). I can think of two situations here. First, the module is already loaded in the project, in which case I will need to find it and add it. And second, the module is not loaded yet so I will need to tell IntelliJ to load it and add it to the project.
The second method takes a Library instance. Just new Library() doesn't work, and google isn't very helpful here. From my buildfile I can extract the groupId:artifactId:version:scope value. So I'll need a way to turn those strings into a Library that works.
This is how far I've gotten so far. Current problems are:
I need to find the already loaded modules so I can find the one I'm linking to
I need a way to add a module to the project if it hasn't been loaded yet
I need a way to turn a maven style dependency into a Library object so I can add it to the module
I need a way to list all the existing modules and libraries so I don't end up adding duplicates

How to use javax.xml.transform.stax in Android Studio?

I'm running into a strange problem in Android Studio. I'm also using latest JDK. I can't seem to import the following :
javax.xml.stream
javax.xml.transform.stax
They both are unavailable and I don't know why. In a non android project I'm able to import these. Any clue why these are missing in android?
If not, the simple solution is that I added these dependencies from maven. But after running I'm getting this error:
"Ill-advised or mistaken usage of a core class (java.* or javax.*) when not building a core library.
Android doesn't use the same Java JDK as what you use for a desktop or server app; it uses its own implementation of the JDK, which adds the android.* hierarchy but leaves out some packages that are in the standard JDK, especially in the javax.* Java extensions. Unfortunately for you, javax.xml.stream and javax.xml.transform.stax are among the things they didn't choose to implement. Moreover, the Android runtime won't allow you to load any java.* or javax.* classes from an external JAR file for security reasons**. This answer may describe the situation a little better.
Your best bets are probably: 1) use a different third-party library specifically built for Android, such as SimpleXML; 2) look for a repackaged version of the libraries, like this JAXB effort; or 3) use a tool like Jar Jar Links to do the repackaging for you.
Also see this excellent guide on parsing JSON and XML in Android.
** Note: I can't find any documentation from Google to substantiate this; it's just a commonly repeated "fact". If anyone can point to an authoritative statement about Android's handling of third-party java[x].* classes, please comment with a link, or edit this answer.

How can I use the nonfree modules in OpenCV for Java?

I want to use SURF for feature detection found here and use it in a Java applicaion, however the nonfree modules are not included in the library by default, as they are patented.
How do I access this module? I have searched and tried a few things but none have worked; many focusing on Android, which I don't fully understand.
Can I add it when using cmake to build the library? or is there a better mean?
Actually when I was using cmake, nonfree library module was selected as default. So you should have this module built in your lib folder. Nonfree module includes some functionality that may be patented in some countries. So you should be careful if you are building a commercial application adn you will sell it in one of these countries.
To use it, you need to add it to your references and include the headers.
EDIT
I checked the docs here : http://docs.opencv.org/java/ there seems to be no module with name nonfree and there is no class related to sift or surf. I thought it should be same with c++ library but I was mistaken.
On the other hand, people claim that they built it for OpenCV4Android. That means it can be somehow compiled unofficially for java as well but no one seems to overcome this. Like here : http://answers.opencv.org/question/11185/how-can-i-generate-java-bindings-for-non-free/
Also there is a issue here about this : http://code.opencv.org/issues/2825
So at the moment no solution out yet. Implementing a JNI and loading compiled c++ nonfree lib may solve the problem by the way.
One more edit :)
In a tutorial, someone implemented JNI for nonfree module to be used with android. I don't have enough knowledge to try it for java at the moment. But a volunteer would be nice to try this with java :
http://web.guohuiwang.com/technical-notes/opencv_nonfree_android_jni_demo

java.lang.NoClassDefFoundError in android

I am new to Android development. I'm working on an project which involves using stubs for web services. When I try to use it, I get the following error:
I've been stuck here for a week, so some help would be highly appreciated.
It seems that there is some packaging or deployment issues with the included libraries that you use in you project. This error is thrown when the Java Virtual Machine or a ClassLoader instace try to load the definition of the a class but cannot find it anywhere. In most cases, this occurs when something is messed up in your project configurations but i cannot tell what from the information provided. A solution would be to configure your project from the scratch since most of the times this is easier than finding what causes the problem. Also in case you had an older version of ADT (<17) the answer of this SO question might be usefull. Finally, if you are importing any javax libararies(or libraries that have javax components in them), this maybe the source of your problem since Adroid does not support the javax library.

Categories