There are several ways that Andorid aka-native code (Java code) could be integrated into Xamarin project. Official ways are listed in this article.
We are trying to use a Java Library Binding approach discribed in the article.
Our test andoid library is published on Github for this question specifically.
We've created it in Android Developer tools setting it as Java Android Library. It is built in Eclipse into a .jar format that tutorial on Xamarin site assumes to be sufficient.
If we are trying to bind .jar into our project in Visual Studio, the Object Explorer will show us the binding asseblie's namespace, but in code, even though the assembly is referenced, we can't access the methods and classes in the namespace, decleared in our test java android lib..
On the other hand, when we take almost any .jar, which is an android library on the internet (for example this one), we can bind it and access it's methods without a problem.
Please compare two .jar and if possible, let me know what is wrong with our test android library on github, that causes our namespace to be unavailable from code.
I read the same Binding a Java Library article you did, went through the instructions, and had no build errors. When I attempted to use the classes from my jar file, intellisense was not recognizing anything. Then I read the follow-on article on API Metadata Reference. This got me thinking that perhaps I should try editing the Transforms/Metadata.xml file. After editing that briefly to include a rename of the package, Visual studio allowed (after a compile) a reference to a class from the jar file. I then attempted to call a method from the class, and again, got another compiler error. So, I went back into the Metadata.xml file and added an entry to rename the method in question. I edited my code to call the renamed method, and Visual Studio compiled fine. I integrated this call into a unit test case, and it passed!
From my reading, it didn't seem necessary to edit the Metadata.xml file, but at least in my experience it seemed necessary. It uses XPATH on the obj/Release/api.xml file (as stated in API Metadata Reference). From that article there were examples for renaming both package & method names, so it wasn't much work for me to insert into my Metadata.xml file. In addition, I downloaded the OsmBindingDroidExample from the Binding a Java Library article and checked out their Metadata.xml file as well.
Here's my XML for reference as well:
<metadata>
<attr path="/api/package[#name='com.abc.def']" name="managedName">MyRenamedPackage</attr>
<attr path="/api/package[#name='com.abc.def']/class[#name='MyClass']/method[#name='originalJavaMethod']" name="managedName">RenamedDotNetMethod</attr>
</metadata>
So, now in my .NET code, I could write:
MyRenamedPackage.MyClass.RenamedDotNetMethod(...);
Hope this helps!
EDIT:
I've gotten a bit more familiar with the Xamarin toolkit, and have an update to make using this easier.
In order to limit the involvement of code that needs to interact with the jar methods, Xamarin allows you to create C# classes in the Additions folder. So, I created a wrapper class that exposes the methods in a managed C# class that other projects can access. Since it's C# there's no complaints from Visual Studio.
Here's what a wrapper class would look like going with my earlier example (obviously you'd pick a name more meaningful to the task at hand):
public class InovcationWrapper
{
public static void InvokeMethod(...)
{
MyRenamedPackage.MyClass.RenamedDotNetMethod(...);
}
}
Then in your project code, you'd have full intellisense if you just call your wrapper class:
InvocationWrapper.InvokeMethod(...);
This makes it much easier to work with and limits the amount of red squiggles to be ignored in your code. Hope this helps!
Related
In java can add:
import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
but how I can do it in my xamarin android app?
You can use a Java Bindings Library to use any AAR or JAR file in Xamarin for Android. Note that, due to some differences between C# and Java, it's possible that you'll have to do a little bit of manual mapping (there's an XML format provided for that). Using this, the compiler will take care of all the JNI bindings and other "plumbing" for you; it'll even convert naming conventions (e.g. prefix interface names with "I").
Are you using xamarin in visual studio ? if yes then you can simply go to tools and then nuget package manager and install packages.More over you can also search packages on nuget.org its the best site
First thing, check nuget if what you look is already there.
If it is not there, use this VS extension:
https://github.com/EgorBo/Xamarin.GradleBindings
Download the extension from here:
https://marketplace.visualstudio.com/items?itemName=EgorBogatov.XamarinGradleBindings
Then after adding the extension to Visual Studio, right click on your reference and then you will see
Add Dependency via gradle
Put the dependency id.
Choose the dependencies you need and download them.
DONT FORGET to put the dependency into your Jar folder (because you might the produced member in your reference dll).
You might need to fix the problems by adding some lines in the metadata.xml*.
If you still don't get any members, you can extract the classes.jar file from the .aar file then rename it to the package file and follow the .jar binding instructions:
https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/binding-a-jar/
*Refer to binding troubleshooting to fix any issue you face (most of the binding needs that step of fixing the metadata.xml): https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/troubleshooting-bindings/ )
I'm working with eclipse mars on ubuntu 15.04.
I'm trying to do the tutorial about volley (https://developer.android.com/training/volley/simple.html) but I'm facing some difficulties.
As explained in this tutorial, I've cloned the volley repository, created an android projet for it, marqued it as a library. I can see that ./src/main/bin/volley.jar is generated, so at that point I would say that everything is good.
Next, I created an Application project and in Projet>Properties>Android I've added volley as a library.
If I well understand the tutorial and some other answers about similar questions I've read, this is the correct way to go.
Anyway, in my code if I try some "import com.android.volley;" I always get the same "The import com.android.volley cannot be resolved".
The only way I can make it work is by adding the source code of volley into my project directly. Obviouly this is not the good solution.
Can someone please tell me what I'm doing wrong ?
Regards
EDIT1:
Thank for the comments but it appears to me that those information are a little bit out of date. If I refer to the git history, volley switched from Gradle to Maven 8 months ago, so it does not build with ant.
Any way, as I said in my question, the project is already building within eclipse so that I have a volley.jar. So I try what is suggested: copie the volley.jar into the libs folder on my project. I'm surprised it does not work :/ Looking closely to the jar file I'm surprised it weighs only 166 bytes!
Referring to https://developer.android.com/tools/projects/projects-eclipse.html:
Creating the manifest file: A library project's manifest file
must declare all of the shared components that it includes, just as
would a standard Android application
and
Declaring library components in the manifest file: In the manifest file of the application project, you must add declarations of all components that the application will use that are imported from a library project. For example, you must declare any <activity>, <service>, <receiver>, <provider>, and so on, as well as <permission>, <uses-library>, and similar elements.
Declarations should reference the library components by their fully-qualified package names, where appropriate.
May it happen that the default manifest file from volley is incorrect and it does not "export" anything which makes the jar file being so small?
Does it mean that I have to put in both manifests (the one from volley and the one of my app) any import I did in my code?
We have developed an iPad application where the core logic is written in CPP code, so that we can use the same code files/libraries to other platforms.
Now I want to use those files and develop similar Android application, but unable to create .so files and integrate paths in Android.mk files and all. I am basically an iOS developer, this is first time I am looking into Android NDK.
Can anyone help and guide if there is any straight forward steps to it.
I have already gone through android developers site and few other tutorial sites. But none of those worked for me.
Require easy-clear steps to call cpp method in java, if I do have few cpp files and .a libraries with me already.
You aren't very specific at the step you are stuck at.
Here's a very quick explanation on how to call native code from java (android) :
first create a method to be exported by the native and called by java (this uses JNI, so google JNI , JNIEXPORT)
once you have this method defined in your native code, it's time to create a shared library (.so) file , using the compiler that comes in the NDK (because you are compiling for android ). You will need to compile for the correct architecture of the device (armeabiv7s is the most common now days).
you need to add the library file in your app.apk inside the armeabi folder (more details in NDK tutorials).
inside your java code you will need to load the shared library via the System.loadLibrary(LIBRARY_NAME);
inside your java code you will need to have defined static native methods that are in pair with the methods you exported from your CPP code
Quick tips :
use C functions,not CPP , since CPP will be mangled in the resulting shared library. In other words, you will need to create a C wrapper that will call your cpp code.
look over a hello world tutorial for NDK , and work yourself from there . Here's a link to such tutorial http://trivedihardik.wordpress.com/2011/06/16/hello-world-example-using-ndk-in-android/
You will bump later on into compilation issues with the makefiles, but by then you will probably be able to be more specific with your question.
Easiest way is to use the hello-jni Android studio sample project.
There are a lot of settings and configurations, you get them from the sample that is a working unit, always easiest when starting from something working.
First run (and modify) the hello-jni and learn how the interactivity between the Java and C parts works. About everything works except environmental ANSI C/C++ stuff. You have to get things like language, country etc from Java and transfer it to the C-code. You are in US in English with "inches and gallons" in JNI.
Then to an own project you create with android studio, copy and modify from it bit by bit from hello-jni. When you have our own branded hello-JNI you can add bit by bit your own code. Often using C-dummies for testing the interactivity with the Java part is easier, then change it to the real C/C++ code of yours.
Read the Android/Android studio documentation and learn and understand. Use the Android emulators, much easier and they are good.
The project configuration stuff is by far the hardest to handle at the start. If I would make a new project today, I would start from the Hello-JNI once again.
I use AndroidAnnotations, and since a couple of days, Eclipse sometimes (not always) fails to compile code that uses classes generated by AndroidAnnotations (pre-compile generated code):
My example is:
My project has MainActivity, AndroidAnnotations creates an extended class MainActivity_ under .apt_generated.
Elsewhere in the DetailActivity, my code has a reference to MainActivity_:
My solution so far was to remove the code, compile, then add the code back. However, this is far from elegant. It also is quite annoying and time-consuming.
Am I missing some setting?
Does the order in the "Order and Export" page have any influence? I've tried to move the .apt_generated directory up and down, with no positive effect.
I was thinking that this is the same concept used by Android's resource class R. I never had any issues with code that use resources failing to compile.
When does that happen?
When you open Eclipse?
When you open a project previously closed?
When you do a project > clean?
This problem looks like a bug in Eclipse. It looks like sometimes it compiles a class, then run the annotation processor, then doesn't update / recompile the classes that had missing symbols.
A simple tricks that seems to do the job: go to the properties of the project, change the name of the annotation processing folder from .apt_generated to something else (and then back to .apt_generated), and accept the rebuild. This seems to trigger a build in the right order, and reset everything right.
Note that AndroidAnnotations uses annotation processing, which is a standard java 6 concept. It's different from the Android R class, which isn't linked to any java standard.
Does that help?
As per comments above from piwai the anwser is:
Eclipse 3.5+ - Annotation processor: Generated classes cannot be imported
I'm just getting started in Android development, and use Netbeans with NBAndroid and SDK 17.
I'd like to use the same Java source code in my Java and Android app.
http://developer.android.com/guide/developing/projects/projects-eclipse.html says how to do it in Eclipse (although it is sketchy on the .JAR connection thing), but I can't seem to make it work in NB.
Based on that link, My understanding is that the correct setup for the Android app is an Android Application project which references an Android Library project which in turn references a .JAR library produced by a Java Library project. I could then also have a Java Application project referring to the same Java Library project.
So, I've set up this project structure... I have an AndroidApp project which is a basic HelloAndroid Activity in a com.ex package. This project includes an AndroidLib library project in the Libraries folder. I also have a LibClass.java file which defines a simple LibClass class which has one function getText() that just returns a String to be displayed. The MainActivity in the AndroidApp calls this to get the String to output.
When I put LibClass.java directly into the AndroidLib project, everything is fine.
But what I want to do is to share the source code with Java.
So I want to move the LibClass.java into the JavaLib library, whose .JAR file is included in the AndroidLib project. However, when I tried that, I get an error in the MainActivity class, complaining it can't find LibClass. Looking at the Projects window, I can see LibClass.class inside the com.ex package in the JavaLib.jar in the Libraries folder of the AndroidLib project. And AndroidLib is visible in the Libraries folder of the AndroidApp project, but it doesn't show any packages or other contents there.
So I feel like I'm just one step away from making this work. Do I need to do something with one or other of the AndroidManifest files perhaps? Or do something with the build.xml files? Or am I on the wrong track altogether?
I'd be really grateful if someone could post a how-to for this.
I'm trying something similar; I've got Java EE projects, built using Eclipse, and I'm trying to utilize some of that code from my Android projects. This should give me a shared codebase rather than a bunch of confusing SVN externals which I've had to endure before.
Rather than creating JAR files I've found that working with the source and building for the platform works best (well, it has been working but I've got a problem with it at the moment). So, what I'm doing is:
c:\MySvnFolderStructure\MyJavaProjectFolder\src\ (and then all the source under that)
c:\MySvnFolderStructure\MyJavaProjectFolder\android\ (and all the Eclipse Android project gubbins)
c:\MySvnFolderStructure\MyJavaProjectFolder\jee\ (and all the Eclipse JEE project gubbins)
The Android and Java EE projects do not have their own src folders, they both link to the src folder in their parent folder. What this means is that each of the Java implementations is building its own byte code version from the source, and using its own external libraries (like the Apache HTTP ones, for example).
Naturally they can't share stuff like awt (as mentioned in another post), but there's plenty of stuff that does cross-over especially if it's core Java classes that are being used.
Also, it's proving a bit tricky writing JUnit tests as there needs to be some duplication of the test code at the moment because the Android ones need extra instrumentation, but I'm working on it.
Also, see this post about relative paths in Eclipse, which means the folders can be checked-out to different places on different machines (like we all do with our version control check-outs) and still be shared.
if I understand your situation correct, you are trying to use a custom java library for both your android and java applications.
For this scenario, you can build the java library first. Instead of adding the java library jar as android library, you can drop the jar directly inside the libs folder of android project and add it to android project's build path.
If you are using ANT scripts for building the java library jar , you can consider adding the source files also as part of jar. This will help you get code assistance when you develop the android part. But this part is purely optional.
The problem is that the Java platform in Android is different from the JDK platform.
In particular, the .JAR library CANNOT refer to anything that is not icluded in the Android platform. An example of things you can't refer to is java.awt.* (except you can have java.awt.fonts).
There is also a difference between JDK String and Android String -- Android does not implement the isEmpty() method.