标准 Android 运行时对象上的 NoMethodError
嘿,我遇到了一个非常奇怪的错误,当尝试在所有 Android 平台上(从 1.5 到 2.2)(在手机和模拟器上)将对象序列化为 JSON 时,我无法解决该错误。
我收到此错误:
E/AndroidRuntime(21017): Uncaught handler: thread AsyncTask #2 exiting due to uncaught exception
E/AndroidRuntime(21017): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(21017): at android.os.AsyncTask$3.done(AsyncTask.java:200)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(21017): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
E/AndroidRuntime(21017): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
E/AndroidRuntime(21017): at java.lang.Thread.run(Thread.java:1096)
E/AndroidRuntime(21017): Caused by: java.lang.NoSuchMethodError: org.json.JSONStringer.object
E/AndroidRuntime(21017): at com.qype.radar.api.json.JsonSerializationHelper.startModel(JsonSerializationHelper.java:119)
E/AndroidRuntime(21017): at com.qype.radar.api.json.JsonSerializationHelper.serializeCheckin(JsonSerializationHelper.java:94)
E/AndroidRuntime(21017): at com.qype.radar.api.QypeApiImpl.submitCheckin(QypeApiImpl.java:157)
E/AndroidRuntime(21017): at com.qype.radar.activities.tasks.SubmitCheckinTask.doCheckedInBackground(SubmitCheckinTask.java:29)
E/AndroidRuntime(21017): at com.qype.radar.activities.tasks.SubmitCheckinTask.doCheckedInBackground(SubmitCheckinTask.java:1)
E/AndroidRuntime(21017): at com.github.droidfu.concurrent.BetterAsyncTask.doInBackground(BetterAsyncTask.java:154)
E/AndroidRuntime(21017): at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/AndroidRuntime(21017): ... 4 more
在序列化此代码中的评论时,从“startModel()”到达“stringer.object”行时:
package com.qype.radar.api.json;
import org.json.JSONException;
import org.json.JSONStringer;
import com.qype.radar.model.Review;
public class JsonSerializationHelper {
private JSONStringer stringer = new JSONStringer();
...
public String serializeReview(Review review) throws JSONException {
startModel("review");
value("rating", review.getRating());
value("language", review.getLanguage());
value("content", review.getText());
return endModel();
}
...
private JSONStringer startModel(String name) throws JSONException {
stringer.object();
stringer.key(name);
stringer.object();
return stringer;
}
private String endModel() throws JSONException {
stringer.endObject();
stringer.endObject();
return stringer.toString();
}
private void value(String key, String value) throws JSONException {
stringer.key(key);
stringer.value(value);
}
private void value(String key, int value) throws JSONException {
stringer.key(key);
stringer.value(value);
}
}
最奇怪的是代码编译良好,并且在调试时,实例化了 JSONStringer 对象好的,但是对它的任何调用都会引发此错误。我还能够使用Java的反射发现该类确实存在,并且我可以从类对象中检索的方法都在那里,并且可以毫无错误地调用。
org.json 包是 Android 中的标准,自 API 版本 1 起就可用。
任何解决此问题的帮助都将不胜感激,因为我根本不知道在哪里查找。
Heya, I get a very strange error that I just cannot sort out when attempting to serialize objects to JSON on all android platforms, from 1.5 through to 2.2 (both on phones and emulators).
I receive this error:
E/AndroidRuntime(21017): Uncaught handler: thread AsyncTask #2 exiting due to uncaught exception
E/AndroidRuntime(21017): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(21017): at android.os.AsyncTask$3.done(AsyncTask.java:200)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(21017): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
E/AndroidRuntime(21017): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
E/AndroidRuntime(21017): at java.lang.Thread.run(Thread.java:1096)
E/AndroidRuntime(21017): Caused by: java.lang.NoSuchMethodError: org.json.JSONStringer.object
E/AndroidRuntime(21017): at com.qype.radar.api.json.JsonSerializationHelper.startModel(JsonSerializationHelper.java:119)
E/AndroidRuntime(21017): at com.qype.radar.api.json.JsonSerializationHelper.serializeCheckin(JsonSerializationHelper.java:94)
E/AndroidRuntime(21017): at com.qype.radar.api.QypeApiImpl.submitCheckin(QypeApiImpl.java:157)
E/AndroidRuntime(21017): at com.qype.radar.activities.tasks.SubmitCheckinTask.doCheckedInBackground(SubmitCheckinTask.java:29)
E/AndroidRuntime(21017): at com.qype.radar.activities.tasks.SubmitCheckinTask.doCheckedInBackground(SubmitCheckinTask.java:1)
E/AndroidRuntime(21017): at com.github.droidfu.concurrent.BetterAsyncTask.doInBackground(BetterAsyncTask.java:154)
E/AndroidRuntime(21017): at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/AndroidRuntime(21017): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/AndroidRuntime(21017): ... 4 more
when arriving at the line 'stringer.object' from 'startModel()' when serializing a review in this code:
package com.qype.radar.api.json;
import org.json.JSONException;
import org.json.JSONStringer;
import com.qype.radar.model.Review;
public class JsonSerializationHelper {
private JSONStringer stringer = new JSONStringer();
...
public String serializeReview(Review review) throws JSONException {
startModel("review");
value("rating", review.getRating());
value("language", review.getLanguage());
value("content", review.getText());
return endModel();
}
...
private JSONStringer startModel(String name) throws JSONException {
stringer.object();
stringer.key(name);
stringer.object();
return stringer;
}
private String endModel() throws JSONException {
stringer.endObject();
stringer.endObject();
return stringer.toString();
}
private void value(String key, String value) throws JSONException {
stringer.key(key);
stringer.value(value);
}
private void value(String key, int value) throws JSONException {
stringer.key(key);
stringer.value(value);
}
}
The strangest thing about this is that the code compiles fine, and upon debugging, the JSONStringer object is instantiated ok, but any calls to it throw this error. I also am able to, using Java's reflection, discover that the class does exist, and the methods I can retrieve from the class object are all there, and can be invoked without error.
The org.json package is a standard in Android, and has been available since API version 1.
Any help to resolve this issue would be appreciated, as I simply don't know where to look.
事实证明,这是来自 Maven Central 的 Android JAR 的问题。它依赖于 JSON JAR,但这些在 Maven Central 上被破坏了(JSONStringer 类是空的,只定义了一个 toString() 方法)。
如果您也使用 Maven,则可以通过使用 maven-android-sdk-deployer 部署 SDK 的 android jar 并从那里开始来解决此问题。
请参阅此帖子
Turns out it was a problem with the Android JAR from Maven Central. It has a dependency on the JSON JARs, but those are broken on Maven Central (the JSONStringer class is empty, only defines a toString() method).
If you're also using Maven, you can fix this by deploying the SDK's android jar using maven-android-sdk-deployer and going from there.
See this thread