I wrote a native module in Android that needs to send data to my React Native JS code.
However, the data I wish to send is a complex model and isn't one of basic types (int, double, array, etc.).
Here is method in the native module:
#ReactMethod
public void getDeviceInfo(final Callback successCallback, final Callback errorCallback) {
successCallback.invoke(new SomeComplexModel());
}
The application crashes (can't find any log) when trying to invoke the success method (same goes when trying to use Promises).
One way to tackle this problem is mapping the complex model into WriteableMap or something like that, but I'd prefer not to.
Do I have another choice?
I followed this tutorial: https://facebook.github.io/react-native/docs/native-modules-android.html
Related
I'm trying to add some android native unit tests for a capacitor plugin I created.
The problem is that the method expects to get a PluginCall object as a param. In iOS it's pretty straightforward. for example:
func test()
{
let data = "madness? THIS. IS. DATA!!!!! ~Leonidas I, King of Data, around 480 BCE"
let plugin = Plugin()
let call = CAPPluginCall(callbackId: "test", options: [
"data": data
], success: { (result, call) in
let resultValue = result?.data["data"] as? Data
XCTAssert(resultValue != nil)
}, error: { (err) in
XCTFail("Error shouldn't have been called")
})
plugin.doSomethingCool(call!)
}
Pretty simple stuff really.
Trying to do the same thing for android, doesn't work quite well.
To instantiate a new PluginCall object I have to pass to the constructor a MessageHandler object, and to instantiate a MessageHandler object I have to pass a Bridge object, to instantiate a bridge object, I have to pass a PluginManager object that the compiler doesn't even recognise. Apparently an impossible task.
Of course I can always just replace the PluginCall param with the actual data, but I want to have a full test coverage for my plugin and not omit huge parts of it just so I can test it. Trying to search this problem online yielded no results, even the official docs doesn't say anything about it, so I turn to SO. Has anyone done something like this before and can point me in the right direction?
TL;DR
How can I create android native unit tests for a capacitor plugin?
Thanks :)
I want to pass data from android native activity to react native js file. I can pass data from react-native to android. But i want to pass when i click button in activity. PLease help me to resolve this issue.
If you want to send object from JavaScript to ReactNative (let's say as an method argument), which is unfortunately not mentioned in documentation:
let map = {
name: 'message1',
surname: 'message2',
}
NativeModules.YourModule.sendObject(map);
And get it in android:
#ReactMethod
public void sendObject(ReadableMap readableMap){
Log.i(TAG, readableMap.toString());
//you can decode it here like:
String name = readableMap.getString("name");
//or just parse it as json
}
Now for the other way (from Java to Javascript) you can use either Callbacs, Promises or Events. This part is described in documentation here
I have this below code.I want to write junit test for this method.
#Override
public void getSuccessData(Response response) {
if(response.getStatus().equalsIgnoreCase("success")){
BaseApplication.getInstance().setAccessToken(response.getToken().getAccessToken());
commonNavigate.navigateToHomeScreen((HomeActivity)view);
}
}
How can i write junit test case for this method.I am very new to junit.
This is (most probably) a callback method you want to test.
If you want to test a callback, you would need to understand mocking.
In very basic terms, mocking lets you create a fake source object and invoke some request method on it, and then verify that a particular callback has been invoked with certain parameters. Read about Mockito, which can be easily integrated with Android Studio: http://site.mockito.org/
Secondly, you code calls android-specific code:
BaseApplication.getInstance().setAccessToken(response.getToken().getAccessToken());
commonNavigate.navigateToHomeScreen((HomeActivity)view);
This code has dependency upon Context object. Please read what Context object means in Android and how it is shared in Application/Activity/View classes. "navigateToHomeScreen" method surely needs a Context!
Either you will mock android dependencies with fake objects, or you could run Instrumented tests which provide Context and other Android-framework-defendant objects.
To sum up - these are wide and complex topics and you should make a research on them first.
Use Mockito framework if you want to test methods. You need to mock objects so that you can test the method with dummy response.
Please refer this link for mockito
https://developer.android.com/training/testing/unit-testing/local-unit-tests.html#setup
I have small app created with Xamarin for android, where I have WebView for displaying some data and than backing up it with C# code for storing data.
To get data from webview I use javascript and in C# I have method like this:
[Export("addMood2")]
[JavascriptInterface]
public String saveData(string data) { ...}
and than I call it from JS code (I have webView.AddJavascriptInterface and all necessary stuff).
So it works if I pass string, but of course in javascript I create some object and what to save it (it more or less always same structure), so for now I stringify it and than passing as string, parsing on C# side and have data.
But is it possible to pass that object from JS directly - as Dictionary or some mapped structure? If I try to use "saveData(Java.Lang.Object data)" data is always null, so I guess it doesn't like type mapping.
For an Android application, I have implemented an external function in C, which I would like to use in two separate classes.
In the first class (my main Activity UI), I call the appropriate loadLibrary:
System.loadLibrary(...);
In the same class, I define the function as native:
public native int dissectPacket(byte[] header, byte[] data, int encap);
After doing this, I can call the native function with no problem in the first class. I do not get any unsatisfied link error.
Now, I want to use this function in another class. I figure I do not need to load the library again. In the second class, at the bottom, I also define:
public native int dissectPacket(byte[] header, byte[] data, int encap);
However, when I try to use the native function in the second class, I get:
07-22 23:13:13.083: ERROR/AndroidRuntime(6737): Caused by: java.lang.UnsatisfiedLinkError: dissectPacket
What is the proper way to use the function in both classes? If I do not redefine the function as native in the second class (called Packet), I get the error:
The method dissectPacket(byte[], byte[], int) is undefined for the type Packet
BTW, I do NOT want to use: class1.dissectPacket(...); I am trying to avoid passing the class.
You defined actually two separate functions. One for the first class and another one for the second. They will need two separate JNI stubs. You, probably, only have stub and implementation for the first one.
JNI and Java, in general, always refer to methods of the specific class.
"BTW, I do NOT want to use: class1.dissectPacket(...); I am trying to avoid passing the class."
If you want to do that, the member functions need to be static, otherwise the class is implicitly passed as a parameter (I don't know how because I've never done it, static functions have always worked for me, but it has to happen to work properly).
So change your method stubs to:
public static native int dissectPacket(byte[] header, byte[] data, int encap);