No se puede convertir una representación en un objeto de clase java.lang.String

Estoy enfrentando un extraño problema mientras desarrollaba un servicio web de restlet + aplicación para Android .

Cuando intento recuperar una cadena del servicio web (implementado localmente en Tomcat 7.0) con una simple obtención, si la cadena del servidor es demasiado grande, la aplicación Android se bloquea con una NullPointerException .

Básicamente, el esquema es el siguiente

aplicación Android

 String retrievedString = clientResource.get(); 

Servidor web

 return serializedString; 

Cuando serializedString tiene un número (no demasiado) de caracteres (por encima de 2k o algo así), retrievedString obtiene un valor null .

No sé cuál es el problema aquí, pero creo que la causa más probable es un límite de memoria, debido a la pila de Android, montón de Java, RAM del sistema o incluso la limitación de VirtualBox / Genymotion.

¿Qué piensas del problema y cómo puedo solucionarlo?


EDITAR

Según lo solicitado, aquí está un poco más de código; Traté de evitar cosas innecesarias y probar / bloquear bloques.

Servidor

  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; 

Cliente

 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>>(){}); 

Excepción

EDIT: Ok, me fue engañado por el color logcat. Es sólo unos pocos días que estoy usando Android Studio y no he notado en absoluto que Log.e() mensajes están escritos en color normal.

Por lo tanto, esto es lo que registra 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) 

En la pregunta original, he omitido que estoy usando Jackson para serializar mis entidades porque parece estar involucrado sólo indirectamente en este problema. Quiero decir, eleva una NullPointerException sólo cuando retrievedString es null.


Código AsyncTask

Según lo solicitado, aquí hay mucho código de mi 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--; } } } } 

Extiende esta clase de 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(); } } 

Está mal uso de su AsyncTask llamando a runOnUiThread() . runOnUiThread() hace exactamente lo que dice que hace: ejecuta el código en el Runnable en el subproceso de interfaz de usuario.

La comunicación de red en Android debe realizarse en un subproceso de fondo, runOnUiThread() rompe ese requisito.

Pruebe esta versión de su 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; } } 

Luego, haga que extienda esta clase:

 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(); } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.