I'm trying to modify chromium on android for research purposes.
Chromium comes with a ContentViewCore.java class. This class calls a native function:
nativeEvaluateJavaScript(mNativeContentViewCore, script, null, true);
This method is defined in the same class as follows:
private native void nativeEvaluateJavaScript(long nativeContentViewCoreImpl,
String script, JavaScriptCallback callback, boolean startRenderer);
The class has the following annotation:
#JNINamespace("content")
As I understand it, the JNI Generator links these methods to the correct native (c++) methods of the correct class.
My question: To which class is ContentViewCore.java linked? Where can I find the implementation of nativeEvaluateJavaScript? Where is it defined that a specific java class is linked to a specific c++ class?
The only thing I can find is content_view_core.h (src/content/public/browser/android), but that file doesn't get me any further. Googeling for 'nativeEvaluateJavaScript' revealed nothing. I've been searching for about 10 hours now and I'm not getting any closer.
The JNI generator will generate JNI binding file under "(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)/jni/" during the build time.
For example, the corresponding JNI binding file for ContentViewCore.java is "out/Debug/gen/content/jni/ContentViewCore_jni.h". And you can see the native method of 'nativeEvaluateJavaScript':
static void EvaluateJavaScript(JNIEnv* env, jobject jcaller,...
Related
I have Mobile Application projects for IOS & Android which internally uses the same Native cpp code. IOS project calls the Native file 'MyNativeFile.cpp' from 'MyApplication.m'. Android project calls the Native file 'MyNativeFile.cpp' through 'MyActivity.java' (Application Layer) via 'MyJNIInterface.cpp' (JNI Interface).
I need a generic implementation in my Native layer file 'MyNativeFile.cpp' through which some char string type data in Native layer can be sent to Application Layers (IOS/Android). (Please note that if I use JNI callback methods like the one mentioned in https://github.com/googlesamples/android-ndk/tree/master/hello-jniCallback it would not work for IOS environment)
My Android Application has below files
MyActivity.java (Application Layer)
MyJNIInterface.cpp (JNI Interface)
MyNativeFile.cpp (Native implementation)
My IOS Project has below files
MyApplication.m (Application Layer)
MyNativeFile.cpp (Native implementation)
One way of doing this is writing the character string to a file from Native code & then reading the same file in Application layer. But this method will have performance issues.
Please suggest a good way for doing this. Share some sample code if possible.
Even I am doing such a project where strings, integer arrays and other longer data types have to be returned.
I need a generic implementation in my Native layer file
'MyNativeFile.cpp' through which some char string type data in Native
layer can be sent to Application Layers
A method for your problem of returning a string can be solved by a reference to string, in your .cpp file, the function should have a parameter of a pointer to a character array, i.e, std::string & varName.
In this parameter, be it your .m file in iOS or JNI in JAVA, all you have to do is first declare an empty in string. Then pass this empty string while you call your function.
The header file of my project is as follows.
//.h file
class FindData {
public:
void findDataPt(int corrOut, string &result_array);
//In this function make changes to result_array directly and they'll reflect on the original string too
};
To call this from .m, I IMPORT THE .h first and then do the following in iOS:
Note: Make the .m as .mm to include C++ includes and functionality
//ViewController.mm
#include <string>
viewDidLoad{
string varName;
FindData fd;
fd. findDataPt(15,varName);
}
After this, make changes to the string, in findDataPt function.
I have a class name String and a String which containing the class code. For example, "Example" is the name of the class, and
public class Example {
public void example () {System.out.println ("Hello world!"); }
}
The class code.
I looked at the Dexmaker library, but I did not understand if it's possible to compile the generated code into it. And the question is just how to compile the code string under Android?
Not sure if possible at all the compilation within the embedded system but definitelly you can parse and run the code using beanshell:
http://www.beanshell.org/
it is lightweight and easily to embed in your app. Then you can instance the generated class and run whatever you put inside.
There is only one true way: using DexMaker. All examples you can find on DexMaker wiki and especially for current problem (runtime generation code on android).
Hi had worked many native called, but are all from classes not from subclasses!
In a nutshell, i have a native method in private static class VideoRender
implements GLSurfaceView.Renderer which is a subclass inside VideoActivity
The native method is giving unsatisfied Linker error for the native declaration of the function
int Java_com_MyFoo_VideoActivity_VideoRender_nativeInit(...)
Please help in solving this! Many examples shows how to use native method from classes, but i want to use it from a subclass
If I'm not mistaken, the right name to give your native function would be:
Java_com_MyFoo_VideoActivity$VideoRender_nativeInit(...)
This corresponds to the way Java "compiles" subclasses: look into your VideoActivity.class file, and you'll see that the VideoRender subclass is probably stored under VideoActivity$VideoRender.
I read that JNI functions (the native C part) is very complex and must contain the java package name.
However, when reading Android webkit source. For example the nativeMoveGeneration functions in WebView.java
private native int nativeMoveGeneration();
It calls the JNI functions in WebView.cpp
static int nativeMoveGeneration(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
if (!view)
return 0;
return view->moveGeneration();
}
Ihis JNI function does not follow naming rule. Why is it?
P/S: The function above is just for demonstration. I'm reading Android 4.0.3 source, so it may be different from the github source above
UPDATE
Thanks to #Alex Cohn and this JNI Tips, I know that we can use JNI_Onload or use complex name. But where should we put JNI_Onload ?
JNI defines special function, JNI_OnLoad. It is called before any JNI method is called, and it can populate the table of native methods using pointers to any C functions. See the official document
I have the follow scenario to work on. I was given a shared library (libeffect.so) to use in a Android project i am working for a client. I dont have the shared library source code, i have just the .so file with me. The library is pre-compiled to work on android devices. Along with the shared library I have the method signature
public static native void doEffect(int param1, IntBuffer intBuffer);
So now I have some questiosn on how to make the call to this native method, of source, if this is possible having just the .so file, so there they are:
Do I need to place the native method signature in the same package/class as those defined when the .so was or I can use this signature in any package/class in my project that during runtime the jvm will be able to find the method in the shared library? For example, if this shared library was firstly used in a class mypackage.MyClass, do I need to create the same package, class and then put the method signature there?
Where do I need to place this .so file inside my eclipse android project to get this file deployed inside my apk file?
These question might sound noob, but I have never worked with jndi before so I am a bit concerned if calling the method doEffect without any error can be achieve. Any answer that can guide me is very welcome.
Many Thanks
Thiago
Do I need to place the native method signature in the same package/class as
those defined when the .so was or I
can use this signature in any
package/class in my project that
during runtime the jvm will be able to
find the method in the shared library?
For example, if this shared library
was firstly used in a class
mypackage.MyClass, do I need to create
the same package, class and then put
the method signature there?
No need to create same package/class. You can put the method signature in any package.
public class NativeLib {
static {
System.loadLibrary("so_file");
}
public static native void doEffect(int param1, IntBuffer intBuffer);
}
2.Where do I need to place this .so file inside my eclipse android project
to get this file deployed inside my apk file?
You have put this .so file in lib folder of your application . IF lib folder is not there then you can create a lib folder and put the .so file. you can call it by using System.loadLibrary("so_ file");
1 Do I need to place the native method signature in the same
package/class as those defined when the .so was or I can use this
signature in any package/class in my project that during runtime the
jvm will be able to find the method in the shared library?
According to http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html you have to use a matching package and class name.
I've only observed JNI methods where the C side functions are called things like Java_com_company_whatever_SomeClass_someMethod, which means that you have to put the 'native' declarations in a similarly-named Java class.
Use the tool 'nm' or 'nm++' (they're in the precompiled folders in the NDK) to look at the .so file and see what the functions defined in it are called. If you see any starting Java_, those're what you want.
I'm sceptical of the preceding claim that you can call functions which aren't named in the Java_PACKAGE_CLASS_METHOD format; it may be a legacy behaviour if it actually works, but even if you can, it seems dangerous - you might get the wrong one.
2 Where do I need to place this .so file inside my eclipse android
project to get this file deployed inside my apk file?
Your .so lives in libs/armeabi, libs/armeabi-v7a, libs/x86, and/or libs/mips depending on how many platforms you're working with, where 'libs' is a peer of 'src' and 'res'. I don't know whether Android looks in libs/ without the platform qualifier, but there's no evident benefit in that. The situation is slightly complicated by most/all Intel devices including fancy technology allowing them to execute most ARM libraries on x86 hardware.
Further, I like to declare an interface of a JNI class and provide a factory (it's a method here for brevity, but I prefer a factory class) that supplies a no-op implementation of the interface if things go wrong: it facilitates unit testing and also avoids having to mess about testing for null values before calling its methods (assuming you're comfortable that your shipped library will never have missing or changed method signatures - your integration tests should check that):
public interface YourLibI {
#Override
public native yourMethod();
public static final NO_OP = new YourLibI() {
#Override
public void yourMethod(){}
}
}
public class YourLib extends YourLibI {
public newYourLibI() {
try {
return new YourLib();
}
catch (UnsatisfiedLinkError e) {
Log.e("YourLibJNI", "Load failed, returning NO-OP dummy", e);
return YourLibI.NO_OP;
}
}
static {
System.loadLibrary("arbitronSDK");
}
private YourLib() {
}
#Override
public native void yourMethod();
}
I don't normally call interfaces 'xxxI' but I'm assuming your library's JNI class isn't called something nice like UtilityJNI (whereupon I'd call the interface 'Utility').