我正在尝试编写插件,以在react-native中获取包名称和图标的applist.我以
JSONArray的形式获得所有必需的数据,图像存储在SD卡中.
我正在使用回调将结果(JSON数组)返回到javascript(成功或失败).我收到了上面提到的错误.
请找到获取详细信息的java代码,如下所示.
package com.sampleapp;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.drawer.ReactDrawerLayoutManager;
import com.facebook.react.views.image.ReactimageManager;
import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReacthorizontalscrollviewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.switchview.ReactSwitchManager;
import com.facebook.react.views.text.ReactRawTextManager;
import com.facebook.react.views.text.ReactTextViewManager;
import com.facebook.react.views.text.ReactVirtualTextViewManager;
import com.facebook.react.views.textinput.ReactTextInputManager;
import com.facebook.react.views.toolbar.ReactToolbarManager;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.react.views.viewpager.ReactViewPagerManager;
public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public static JSONArray applist;
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ToastAnd";
}
@ReactMethod
public void show(Callback errorCallback,Callback successCallback) {
try {
//get a list of installed apps.
PackageManager pm = getReactApplicationContext().getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(0);
JSONArray app_list = new JSONArray();
int cnt = 0;
String path = getSdpath();
makeRootDirectory(path + "/com.framework.xxx/");
makeRootDirectory(path + "/com.framework.xxx/Cache/");
for (ApplicationInfo packageInfo : packages) {
try {
if (getReactApplicationContext().getPackageManager().getLaunchIntentForPackage(packageInfo.packageName) != null) {
JSONObject info = new JSONObject();
info.put("name",packageInfo.loadLabel(pm));
info.put("packagename",packageInfo.packageName);
String img_name = "/com.ionicframework.xxx/Cache/" + packageInfo.packageName + ".png";
info.put("img",path + img_name);
//cheak exist or not
File cheakfile = new File(path + img_name);
if (!cheakfile.exists()) {
Drawable icon = pm.getApplicationIcon(packageInfo);
if (icon != null) {
drawabletofile(icon,path + img_name);
}
}
app_list.put(cnt++,info);
}
} catch (Exception ex) {
System.err.println("Exception: " + ex.getMessage());
}
}
applist = app_list;
successCallback.invoke(applist);
} catch (Exception e) {
errorCallback.invoke(e.getMessage());
}
}
public static void drawabletofile(Drawable drawable,String path)
{
File file = new File(path);
Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100 /*ignored for PNG*/,bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(bitmapdata);
} catch (IOException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
}
public String getSdpath()
{
File SDdir = null;
boolean sdCardExist= Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(sdCardExist){
SDdir=Environment.getExternalStorageDirectory();
}
if(SDdir!=null){
return SDdir.toString();
}
else{
return null;
}
}
public static void makeRootDirectory(String filePath) {
File file = null;
try {
file = new File(filePath);
if (!file.exists()) {
file.mkdirs(); //make Directory
}
} catch (Exception e) {
e.printstacktrace();
}
}
}
在android.index.js中我正在调用本机方法,如下所示:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
AppRegistry,StyleSheet,Text,View,} = React;
var toastMessage = require('./sampletoast');
toastMessage.show(
(msg) => { console.log(msg); },(result) => { alert(JSON.stringify(result)); }
);
var SampleApp = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started,edit index.android.js
</Text>
<Text style={styles.instructions}>
Shake or press menu button for dev menu
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},welcome: {
fontSize: 20,textAlign: 'center',margin: 10,instructions: {
textAlign: 'center',color: '#333333',marginBottom: 5,});
AppRegistry.registerComponent('SampleApp',() => SampleApp);
但是在java代码中返回applist(successCallback.invoke(applist);)我得到了上面提到的错误.
你能在我做错的地方帮助我吗?谢谢
详细错误:
Exception in native call from JS 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: java.lang.RuntimeException: Cannot convert argument of type class org.json.JSONArray 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.Arguments.fromJavaArgs(Arguments.java:55) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.CallbackImpl.invoke(CallbackImpl.java:27) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.sampleapp.ToastModule.show(ToastModule.java:100) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at java.lang.reflect.Method.invokeNative(Native Method) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at java.lang.reflect.Method.invoke(Method.java:515) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.BaseJavaModule$JavaMethod.invoke(BaseJavaModule.java:106) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.NativeModuleRegistry$ModuleDeFinition.call(NativeModuleRegistry.java:143) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.NativeModuleRegistry.call(NativeModuleRegistry.java:64) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.CatalystInstance$NativeModulesReactCallback.call(CatalystInstance.java:366) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at android.os.Handler.handleCallback(Handler.java:733) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at android.os.Handler.dispatchMessage(Handler.java:95) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at android.os.Looper.loop(Looper.java:136) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at com.facebook.react.bridge.queue.MessageQueueThread$1.run(MessageQueueThread.java:137) 11-14 09:01:24.780 20592-20624/com.sampleapp E/unkNown:React: at java.lang.Thread.run(Thread.java:841)
解决方法
使用Native桥时,应使用com.facebook.react.bridge包中的WritableNative组件调用回调.
而不是JSONObject,使用WritableNativeMap.
而不是JSONArray,使用WritableNativeArray.
例如,使用WritableNativeMap:
@ReactMethod
public void reactMethod(Callback onSuccess) {
WritableMap resultData = new WritableNativeMap();
resultData.putString("key1","data");
resultData.putString("key2","data2");
onSuccessCallback(resultData);
}
在你的情况下,你应该有类似的东西:
public static WritableArray applist;
// ...
@ReactMethod
public void show(Callback errorCallback,Callback successCallback) {
try {
//get a list of installed apps.
PackageManager pm = getReactApplicationContext().getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(0);
WritableArray app_list = new WritableNativeArray();
// ...
for (ApplicationInfo packageInfo : packages) {
try {
if (getReactApplicationContext().getPackageManager().getLaunchIntentForPackage(packageInfo.packageName) != null) {
WritableMap info = new WritableNativeMap();
info.putString("name",packageInfo.loadLabel(pm).toString());
info.putString("packagename",packageInfo.packageName);
// ...
app_list.pushMap(info);
}
} catch (Exception ex) {
System.err.println("Exception: " + ex.getMessage());
}
}
applist = app_list;
successCallback.invoke(applist);
} catch (Exception e) {
errorCallback.invoke(e.getMessage());
}
}