react-native android中出现此问题“无法转换类型为org.json.JSONArray的参数”的原因是啥?
Posted
技术标签:
【中文标题】react-native android中出现此问题“无法转换类型为org.json.JSONArray的参数”的原因是啥?【英文标题】:What is cause for this issue "Cannot convert argument of type class org.json.JSONArray" in react-native android?react-native android中出现此问题“无法转换类型为org.json.JSONArray的参数”的原因是什么? 【发布时间】:2016-02-15 23:57:45 【问题描述】:我正在尝试编写插件以在 react-native 中获取带有包名称和图标的应用列表。我以 JSONArray 的形式获取所有必需的数据,并且图像存储在 sdcard 中。
我正在使用回调将结果(JSON 数组)返回给 javascript(成功或失败)。我收到上述错误。
请在下面找到获取详细信息的 java 代码。
包 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)
【问题讨论】:
【参考方案1】:在使用原生桥时,应使用 WritableNative
包中的 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());
【讨论】:
感谢您回复阿尔莫罗。我没有得到你。你能解释一下吗。你的意思是说我需要以键值形式存储? 当我按照你说的写的时候,它的显示异常:org.json.JSONArray cannot be cast to com.facebook.react.bridge.WritableArray error 糟糕,我没有仔细阅读您的代码。我正在编辑我的答案。 没问题的兄弟。谢谢 有人能给我指点WritableNativeArray
和WritableNativeMap
的文档吗?以上是关于react-native android中出现此问题“无法转换类型为org.json.JSONArray的参数”的原因是啥?的主要内容,如果未能解决你的问题,请参考以下文章
“需要使用Adobe Application Manager 解决此问体,但其已丢失或损坏。”
Android执行react-native run android命令出现A problem occurred evaluating project’:app’解决方案
React-native 关于 android真机 出现连不上服务器
尝试在 MI MAX 2 android 设备上运行 react-native 应用程序时应用程序期间出现 SecurityException:installDebug 任务