Android can use .so file through JNI. The native function in C/C++ is bound to a Java function.
I want to use other developers' .so file (I don't have the source code). I know the interface of the native function, but I have faced some difficulties. It seems that the .so file is hard coded to bind for a certain package name.
Is there any way for me to use other developers' .so file?
If not, is it possible to decompile the .so file and make it work?
You could create a package with the name that the shared object expects, in which you have a wrapper class whose only purpose is to load the library and provide the native methods to clients using this class.
Import that package into your own activity's package (or wherever you want to use it) and call the native methods through the wrapper class.
Related
I have a java file which loads .so files and prints the result coming from .so file. I don't have a source code for my .so file. Can anyone tell how in the memory structure .so results are loaded and from where this Java class is reading the results generated by .so and printing them out??
If u have any code that is already written in native language and reluctant about changing it but you would want to use native calls in your java codes and not to rewrite entirely everything java. JNI comes in handy. it converts all your platform specific implementations to platform independent. Performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality.
the library files .so are converted in such a manner.
JNIEnv contains all types of conversion from a native data types to the java data types. it also supports suitable implementations for native method calls, signals are also handled by the JVM.
Java being platform independent native processss specific to a hardware and operating system platform are all made platform independent by mapping native data types and method calls to java. JNI performs the above using the library files example .so or .a files
For JNI mapping u can refer the below link
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
Your .so have a JNI glue class that binds all your Java native methods (public native void x();) with compiled native code.
I'm assuming it uses JNI, otherwise I have no idea how its working. If it uses JNI, then it actually creates Java objects on the Java heap in the .so, using the JNI libraries. Look for functions marked "native", these functions map directly to functions in the so that are called when th Java code whats to run something in the library.
The Droidfish Android chess game is written in Java. But its underlying chess engine Stockfish is written in C++. At first, I thought there was a JNI layer that connects these two but there isn't. The C++ stockfish executable is launched, and Java and C++ communicates via stream.
You can launch the C++ stockfish and play with this engine in the command line, no graphical interfaces.
In your question, your native .so library is printing something to stdout/stderr and you want to read these outputs in Java?
We have a c++ project on android, which will be built into .a then release the .a to our users.
The problem is, we have many resource files, and these resources' path is necessary because some 3rd-party libs need them.
The limitation on android is: if we want to put a file in Android APK, we must package it in res or assets and it is not single file any more, so how can we organize our resources?
Our plan is to require our users to package our resources in APK's Assets, then we can extract them to other folder, but it's not user-friendly, do you have any better idea?
thanks
C++ android project, it sounds me weird, may be, you would like to say that you have c++ arm crosscompiled static library .a which it is able to load in an Android project.
I guess you want to share a library which uses many resources, and you need the elegant way to distribute.
Try to create a .jar file which it has native functions:
Firstly create your core class exporting functions and define your
public native functions to JNI.
Don't use activities, if you need to access to activity context, pass
through parameters.
If you want to use resources, your layouts will not be able to use in
your parent android project.
You can use drawable files and you can add layout files programatically (with activity context).
If you are going to use some resources such as xml config files, put
in the res/raw folder or in assets folder.
If you have good Java and JNI skills, this task is not so difficult.
Hope the advices help you.
Cheers.
I think you need to develope a NativeActivity. If you follow the proper documentation, you could create a working app to do whatever you want. If you want to open assets, process, you can do it, and launch this app from another one.
If you really want a single library to be used, Just do it in c/cpp, and initialize it with a JNI function call providing the asset path and aassetmanager, and use the AAssetManager object in native. You will need to include jni.h, of course you will need to crosscompile the library using the NDK toolchain, and gradle or cmake toolchain scripts.
When I make an app with package name com.example.app, src/com/example/app/MainActivity.java is created automatically. I am new to Java and I don't understand
why it uses so many folders inside folders? Why isn't it just src/MainActivity.java?
In order to avoid namespace collisions and conflicts, it's a common best practice in Java nest source code within a folder structure that is the reverse of the internet site associated with it. If everyone created jar library files in the root /src directory, eventually you'd have a collision and the code wouldn't be usable.
For instance, if I have some fancy Android library and I provided a class called Button, in a Button.java class, and you also at times wanted to use some other library that also had a Button.java in /src, your project would not compile.
Thus, in order to let everyone have their own unique Button class, the convention that was adopted was for everyone to use their reverse domain name, followed often by the project name. So the Facebook SDK, fo instance, has /src/com/facebook/android/Util.java while my own project has /src/com/myapp/misc/Util.java and I can use and reference both in my source code.
Is there a way to get the application's directory to save private data to a file for my application directly from the NDK? In other words, I need an equivalent of the Java function mContext.getFilesDir().
I have noted that other posts such as this one:
Android NDK Write File
mention what is the 'usual' place for this directory to be. But for it to be correct in all versions and all devices, an equivalent system call is surely necessary.
I am currently using a NativeActivity and no Java at all.
Thank you for your time.
I have custom helper class for accessing various paths, for the data directory I do this:
Read /proc/self/cmdline or /proc/**MyPID**/cmdline
Append the results from #1 to /data/data/
Example results:
/data/data/com.yourcompany.yourproduct/
If you are using NativeActivity then you have access from native code to an ANativeActivity instance (see <ndk_root>/platforms/android-9/arch-arm/usr/include/android/native_activity.h) which has internalDataPath and externalDataPath members.
I would like to use third party classes for which I have no source code. How do I instantiate these classes (which are in an APK on the phone) if I have no source code. Is it possible to do in Java? If not, how can it be done?
What exactly are you trying to do? If you can root your phone I guess you could pull the APK off and try to analyze what the classes are doing using something like Apktool..
How do I instantiate these classes (which are in an APK on the phone) if I have no source code.
If the classes are in your project (as a JAR or source code), you use them normally, like any other class. If you do not know how to do that, contact whoever wrote the code and obtain documentation for them.
If the classes are not in your project, you cannot use them.