[英]Unable to convert a [text/plain,UTF-8] representation into an object of class java.lang.String
在開發restlet web服務+ Android
應用程序時,我遇到了一個奇怪的問題。
當我嘗試使用簡單的get從Web服務(在Tomcat 7.0本地部署)中恢復String時,如果服務器中的字符串太大,則Android應用程序會因NullPointerException
崩潰。
基本上,該計划如下
Android應用
String retrievedString = clientResource.get();
網絡服務器
return serializedString;
當serializedString
有一個(不太)大量的字符(大於2k或類似的東西)時, retrievedString
得到一個null
值。
我不知道這里有什么問題,但我認為最可能的原因是內存限制,因為Android堆,Java堆,系統RAM或甚至VirtualBox / Genymotion限制。
您如何看待這個問題,我該如何解決?
根據要求,這里有一些代碼; 我試圖避免不必要的東西和try / catch塊。
服務器
ObjectMapper objectMapper = new ObjectMapper();
FilterProvider excludeThreadFilter =
new SimpleFilterProvider().addFilter("filter properties by name",
SimpleBeanPropertyFilter.serializeAllExcept("email", "password",
"threads", "messages", "subforumsSet", /*"parentSubforum",
"registeredDate", "threadSubforum"*/));
String st = objectMapper.writer(excludeThreadFilter).writeValueAsString(lt);
return st;
客戶
ClientResource cr = new ClientResource("...an ip address...");
ThreadsInSubforumIdByPage tis = cr.wrap(ThreadsInSubforumIdByPage.class);
// The line below is null
String retrievedString = tis.getThreads();
// The line below raise the NullPointerException
List<Thread> retrievedList =
DataHolder.getHolder().getObjectMapper().readValue(
retrievedString, new TypeReference<List<Thread>>(){});
例外
編輯:好的,我被logcat顏色誤導了。 我使用Android Studio只有幾天時間,我根本沒有注意到Log.e()
消息是用正常顏色寫的。
所以,這就是logcat報告的內容
5 .../W/System.err﹕ Unable to convert a [text/plain,UTF-8] representation into an object of class java.lang.String
5 .../W/System.err﹕ [ 175 3749: 3749 W/System.err ]
android.os.NetworkOnMainThreadException
5 .../W/System.err﹕ at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
5 .../W/System.err﹕ at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:158)
5 .../W/System.err﹕ at libcore.io.IoBridge.recvfrom(IoBridge.java:525)
5 .../W/System.err﹕ at java.nio.SocketChannelImpl.readImpl(SocketChannelImpl.java:305)
5 .../W/System.err﹕ at java.nio.SocketChannelImpl.read(SocketChannelImpl.java:267)
5 .../W/System.err﹕ at org.restlet.engine.io.ReadableSocketChannel.read(ReadableSocketChannel.java:82)
5 .../W/System.err﹕ at org.restlet.engine.connector.Connection$1.read(Connection.java:232)
5 .../W/System.err﹕ at org.restlet.engine.io.Buffer.fill(Buffer.java:395)
5 .../W/System.err﹕ at org.restlet.engine.io.ReadableBufferedChannel.onFill(ReadableBufferedChannel.java:157)
5 .../W/System.err﹕ at org.restlet.engine.io.Buffer.process(Buffer.java:601)
5 .../W/System.err﹕ at org.restlet.engine.io.ReadableBufferedChannel.read(ReadableBufferedChannel.java:176)
5 .../W/System.err﹕ at org.restlet.engine.io.Buffer.fill(Buffer.java:395)
5 .../W/System.err﹕ at org.restlet.engine.io.NbChannelInputStream.onFill(NbChannelInputStream.java:189)
5 .../W/System.err﹕ at org.restlet.engine.io.Buffer.process(Buffer.java:601)
5 .../W/System.err﹕ at org.restlet.engine.io.NbChannelInputStream.read(NbChannelInputStream.java:307)
5 .../W/System.err﹕ at java.io.InputStream.read(InputStream.java:163)
5 .../W/System.err﹕ at org.restlet.engine.io.BioUtils.copy(BioUtils.java:81)
5 .../W/System.err﹕ at org.restlet.engine.io.NioUtils.copy(NioUtils.java:148)
5 .../W/System.err﹕ at org.restlet.representation.ReadableRepresentation.write(ReadableRepresentation.java:104)
5 .../W/System.err﹕ at org.restlet.representation.ChannelRepresentation.write(ChannelRepresentation.java:76)
5 .../W/System.err﹕ at org.restlet.representation.ChannelRepresentation.write(ChannelRepresentation.java:82)
5 .../W/System.err﹕ at org.restlet.representation.Representation.getText(Representation.java:397)
9 .../W/System.err﹕ at org.restlet.engine.converter.DefaultConverter.toObject(DefaultConverter.java:260)
9 .../W/System.err﹕ at org.restlet.service.ConverterService.toObject(ConverterService.java:170)
9 .../W/System.err﹕ at org.restlet.resource.Resource.toObject(Resource.java:828)
9 .../W/System.err﹕ at org.restlet.engine.resource.ClientInvocationHandler.invoke(ClientInvocationHandler.java:240)
9 .../W/System.err﹕ at $Proxy23.getThreads(Native Method)
9 .../W/System.err﹕ at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground.loadThreads(SubforumContentActivity.java:329)
9 .../W/System.err﹕ at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground.access$400(SubforumContentActivity.java:283)
9 .../W/System.err﹕ at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground$1.run(SubforumContentActivity.java:301)
9 .../W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:615)
9 .../W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:92)
9 .../W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
9 .../W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:4745)
9 .../W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
9 .../W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
9 .../W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
9 .../W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
9 .../W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
[ 187 3749: 3749 E/class com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground NullPointerException
java.lang.NullPointerException
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:822)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2153)
at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground.loadThreads(SubforumContentActivity.java:331)
at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground.access$400(SubforumContentActivity.java:283)
at com.gmail.tigerjack89.pervasive.forum.SubforumContentActivity$LoadThreadsInBackground$1.run(SubforumContentActivity.java:301)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
在最初的問題中,我省略了我使用Jackson
來序列化我的實體,因為似乎只是間接地涉及這個問題。 我的意思是,只有當retrievedString
為null時才會引發NullPointerException
。
根據要求,這里有很多來自我的AsynkTask的代碼
private class LoadThreadsInBackground extends LoadFromServerInBackground
{
public LoadThreadsInBackground()
{
super(SubforumContentActivity.this);
}
@Override
protected Void doInBackground(final Boolean... params)
{
runOnUiThread(
new Runnable()
{
@Override
public void run()
{
currentThreadsPosition = threadsListView.getFirstVisiblePosition();
// Appending new data to threadsList
loadThreads(params[0]);
// Setting new scroll position
threadsListView.setSelectionFromTop(currentThreadsPosition + 1, 0);
}
});
return (null);
}
private void loadThreads(boolean reload)
{
if (reload) threadList.clear();
ClientResource cr = new ClientResource("IP address");
cr.setChallengeResponse(getAuthentication());
ThreadsInSubforumIdByPage tis = cr.wrap(ThreadsInSubforumIdByPage.class);
List<Thread> retrievedList;
String s = tis.getThreads();
retrievedList =
getObjectMapper().readValue(
s, new TypeReference<List<Thread>>(){});
threadList.addAll(retrievedList);
if ((retrievedList == null) || (retrievedList.size() < Constants
.RETRIEVED_PER_PAGE))
{
loadMoreThreadsButton.setEnabled(false);
if (retrievedList != null && retrievedList.size() == 0)
{ currentThreadsPage--; }
}
}
}
它擴展了這個abstact類
public abstract class LoadFromServerInBackground extends AsyncTask<Boolean, Void, Void>
{
private ProgressDialog mProgressDialog;
private Activity mInvokerActivity;
public LoadFromServerInBackground(Activity invokerActivity)
{
mInvokerActivity = invokerActivity;
}
@Override
protected void onPreExecute()
{
// Showing progress dialog before sending http request
mProgressDialog = new ProgressDialog(mInvokerActivity);
mProgressDialog.setMessage("Please wait ...");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
@Override
protected void onPostExecute(Void unused)
{
// closing progress dialog
mProgressDialog.dismiss();
}
}
您通過調用runOnUiThread()
來濫用您的AsyncTask
。 runOnUiThread()
完全按照它的說法執行:在UI線程上執行Runnable
的代碼。
Android上的網絡通信必須在后台線程上執行, runOnUiThread()
會破壞該要求。
試試這個版本的AsyncTask
:
private class LoadThreadsInBackground extends LoadFromServerInBackground<List<Thread>> {
int currentThreadsPosition;
boolean reload;
public LoadThreadsInBackground() {
super(SubforumContentActivity.this);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
currentThreadsPosition = threadsListView.getFirstVisiblePosition();
}
@Override
protected List<Thread> doInBackground(final Boolean... params) {
reload = params[0];
// Load data from network
return loadThreads();
}
@Override
protected void onPostExecute(List<Thread> retrievedList) {
super.onPostExecute(retrievedList);
if (reload) {
threadList.clear();
}
// Appending new data to threadsList
threadList.addAll(retrievedList);
if ((retrievedList == null) || (retrievedList.size() < Constants.RETRIEVED_PER_PAGE)) {
loadMoreThreadsButton.setEnabled(false);
if (retrievedList != null && retrievedList.size() == 0) {
currentThreadsPage--;
}
}
threadsListView.setSelectionFromTop(currentThreadsPosition + 1, 0);
}
private List<Thread> loadThreads() {
ClientResource cr = new ClientResource("IP address");
cr.setChallengeResponse(getAuthentication());
ThreadsInSubforumIdByPage tis = cr.wrap(ThreadsInSubforumIdByPage.class);
String s = tis.getThreads();
List<Thread> retrievedList = getObjectMapper().readValue(s, List<Thread>.class);
return retrievedList;
}
}
然后,讓它擴展這個類:
public abstract class LoadFromServerInBackground<T> extends AsyncTask<Boolean, Void, T> {
private ProgressDialog mProgressDialog;
private Activity mInvokerActivity;
public LoadFromServerInBackground(Activity invokerActivity) {
mInvokerActivity = invokerActivity;
}
@Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
mProgressDialog = new ProgressDialog(mInvokerActivity);
mProgressDialog.setMessage("Please wait ...");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
@Override
protected void onPostExecute(T unused) {
// closing progress dialog
mProgressDialog.dismiss();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.