Intereting Posts
Как изменить стиль по умолчанию EditText Связанные столбцы рушатся на веб-браузере Android (при использовании страниц автоматической установки) Есть ли бесплатная библиотека OCR для Android? Как избежать черного экрана при запуске приложения Как изменить стек Bluetooth для Android, чтобы включить A2dp Sink Постоянное обновление текущего уведомления Блокировка / разблокировка экрана Android программно Как мы можем не допустить, чтобы Служба была убита ОС? Как обфускать мой проект андроида в Eclipse IDE? NoClassDefFoundError для библиотеки .jar во время выполнения в Android Studio File.delete () не удаляет полностью пустой файл образа изображения Как скрыть URL-адрес в пользовательской вкладке Chrome android Только в некоторых телефонах ListView не обновляется после notifyDataSetChanged () Android: программно удалить мое приложение от администратора устройства? Смешивание кордовой и родной деятельности в Android

Джерси-клиент на Android – NullPointerException

Я пытаюсь создать простой клиент Android для веб-службы, которую я создал, но что-то не так во время выполнения.

Вот клиент:

public class MyClient extends AsyncTask<EditText, Integer, String> { private EditText text; protected String doInBackground(EditText... strings) { RuntimeDelegate .setInstance(new com.sun.ws.rs.ext.RuntimeDelegateImpl()); WebResource wbr; Client client = Client.create(); wbr = client .resource("http://my.ip:8080/MazeService/rest/service/hello"); String result = wbr.queryParam("number", "10") .accept(MediaType.APPLICATION_JSON).get(String.class); text = strings[0]; return result; } protected void onProgressUpdate(Integer... progress) { // setProgressPercent(progress[0]); } protected void onPostExecute(String result) { if (result != null) this.text.setText(result); else Log.d("MyApp", "No Result"); } 

}

И Служба:

 @Path("/service") public class AndroidService { @GET @Produces(MediaType.APPLICATION_JSON ) @Path("/hello") public String getJSON(@QueryParam("number") String nr) { String s = "Hi there! The number is: "+nr; return s; } } 

Я получаю этот стек в LogCat:

 02-18 16:26:06.446: E/AndroidRuntime(1381): FATAL EXCEPTION: AsyncTask #1 02-18 16:26:06.446: E/AndroidRuntime(1381): java.lang.RuntimeException: An error occured while executing doInBackground() 02-18 16:26:06.446: E/AndroidRuntime(1381): at android.os.AsyncTask$3.done(AsyncTask.java:278) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 02-18 16:26:06.446: E/AndroidRuntime(1381): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.lang.Thread.run(Thread.java:856) 02-18 16:26:06.446: E/AndroidRuntime(1381): Caused by: java.lang.NullPointerException 02-18 16:26:06.446: E/AndroidRuntime(1381): at javax.ws.rs.core.MediaType.valueOf(MediaType.java:119) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.ClientResponse.getType(ClientResponse.java:615) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:532) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.WebResource.handle(WebResource.java:674) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:503) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.maze.client.MyClient.doInBackground(MyClient.java:25) 02-18 16:26:06.446: E/AndroidRuntime(1381): at com.maze.client.MyClient.doInBackground(MyClient.java:1) 02-18 16:26:06.446: E/AndroidRuntime(1381): at android.os.AsyncTask$2.call(AsyncTask.java:264) 02-18 16:26:06.446: E/AndroidRuntime(1381): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 02-18 16:26:06.446: E/AndroidRuntime(1381): ... 5 more 

Я не понимаю, в чем проблема, так как аналогичный клиент работает на ПК. Нет проблем с IP-адресом, так как я могу получить доступ к серверу с Android VirtualDevice.

Версия Android 4.0.3 API версии 15. Для клиента я использовал Jersey 1.11.

РЕДАКТИРОВАТЬ

Я также попытался удалить все это с помощью EditText, так как кто-то сказал мне, что он не используется так, как должно быть. Тем не менее, у меня такая же ошибка. Я просто не понимаю, что я делаю неправильно. Если я покажу любую другую дополнительную информацию, сообщите мне. Кроме того, ЛЮБАЯ идея хороша. Я новичок в Android, и я, возможно, допустил некоторые глупые ошибки.

Solutions Collecting From Web of "Джерси-клиент на Android – NullPointerException"

Предложение Павла верное. Я немного глубже в этом вопросе и нашел причину.

Инструмент упаковки Android apk (класс APKBuilder из sdklib.jar) игнорирует разные папки, пока он создает пакет ( источник ). Одна из этих папок – META-INF – независимо от того, находится ли она в прикрепленной библиотеке или в исходной папке проекта.

Обходной путь для версии 1.8 (и, возможно, другой, но я не тестировал его) в Джерси, должен предоставить пользовательские (по умолчанию один ищет META-INF / services / который отсутствует в android apk) для ServiceFinder $ ServiceIteratorProvider, который имеет Жесткие кодированные имена классов поставщика. Я основывал свою реализацию на этой реализации, предложенной Лукасом:

 import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import android.util.Log; import com.sun.jersey.spi.service.ServiceFinder.ServiceIteratorProvider; public class AndroidServiceIteratorProvider<T> extends ServiceIteratorProvider<T> { private static final String TAG = AndroidServiceIteratorProvider.class.getSimpleName(); private static final String MESSAGE = "Unable to load provider"; private static final HashMap<String, String[]> SERVICES = new HashMap<String, String[]>(); private static final String[] com_sun_jersey_spi_HeaderDelegateProvider = { "com.sun.jersey.core.impl.provider.header.MediaTypeProvider", "com.sun.jersey.core.impl.provider.header.StringProvider" }; private static final String[] com_sun_jersey_spi_inject_InjectableProvider = { }; private static final String[] javax_ws_rs_ext_MessageBodyReader = { "com.sun.jersey.core.impl.provider.entity.StringProvider", "com.sun.jersey.core.impl.provider.entity.ReaderProvider" }; private static final String[] javax_ws_rs_ext_MessageBodyWriter = { "com.sun.jersey.core.impl.provider.entity.StringProvider", "com.sun.jersey.core.impl.provider.entity.ReaderProvider" }; static { SERVICES.put("com.sun.jersey.spi.HeaderDelegateProvider", com_sun_jersey_spi_HeaderDelegateProvider); SERVICES.put("com.sun.jersey.spi.inject.InjectableProvider", com_sun_jersey_spi_inject_InjectableProvider); SERVICES.put("javax.ws.rs.ext.MessageBodyReader", javax_ws_rs_ext_MessageBodyReader); SERVICES.put("javax.ws.rs.ext.MessageBodyWriter", javax_ws_rs_ext_MessageBodyWriter); SERVICES.put("jersey-client-components", new String[]{}); SERVICES.put("com.sun.jersey.client.proxy.ViewProxyProvider", new String[]{}); } @SuppressWarnings("unchecked") @Override public Iterator<Class<T>> createClassIterator(Class<T> service, String serviceName, ClassLoader loader, boolean ignoreOnClassNotFound) { String[] classesNames = SERVICES.get(serviceName); int length = classesNames.length; ArrayList<Class<T>> classes = new ArrayList<Class<T>>(length); for (int i = 0; i < length; i++) { try { classes.add((Class<T>) Class.forName(classesNames[i])); } catch (ClassNotFoundException e) { Log.v(TAG, MESSAGE,e); } } return classes.iterator(); } @Override public Iterator<T> createIterator(Class<T> service, String serviceName, ClassLoader loader, boolean ignoreOnClassNotFound) { String[] classesNames = SERVICES.get(serviceName); int length = classesNames.length; ArrayList<T> classes = new ArrayList<T>(length); for (int i = 0; i &lt; length; i++) { try { classes.add(service.cast(Class.forName(classesNames[i]) .newInstance())); } catch (IllegalAccessException e) { Log.v(TAG, MESSAGE,e); } catch (InstantiationException e) { Log.v(TAG, MESSAGE,e); } catch (ClassNotFoundException e) { Log.v(TAG, MESSAGE,e); } } return classes.iterator(); } } 

Я удалил большинство классов, так как не использовал их, а также они вызывали ошибки проверки на dalvik vm …

ПРИМЕЧАНИЕ. Это означает, что с этой реализацией вы можете использовать только подмножество заголовков / типов, поддерживаемых Джерси (мне нужна только строка). Для поддержки других типов вам необходимо добавить поставщиков, находящихся в папке META-INF / services jersey-client.jar (или из реализации Lucas), и проверить, не вызывают ли они ошибки проверки на Android.

Вышеприведенный код следует использовать следующим образом:

 ServiceFinder.setIteratorProvider(new AndroidServiceIteratorProvider()); Client client = Client.create(); 

РЕДАКТИРОВАТЬ:

Похоже, проблема была исправлена в Android-maven-plugin.

Mosa … @ gmail.com написал:

Запрос тяги с исправлением был объединен с мастером и будет выпущен с 3.2.1:

Следуя коду:

ком / ВС / Джерси / API / клиент / ClientResponse.getType ()

 613 public MediaType getType() { 614 String ct = getHeaders().getFirst("Content-Type"); 615 return (ct != null) ? MediaType.valueOf(ct) : null; 616 } 

Я бы проверял, что делегат, используемый MediaType, не является null .

javax / WS / RS / ядро / MediaType.valueOf (java.lang.String)

 118 public static MediaType valueOf(String type) throws IllegalArgumentException { 119 return delegate.fromString(type); 120 } 

Похоже, что delegate имеет значение null для одного клиента (Android), а не для другого клиента.

Взгляните на это, чтобы понять, как инициализируется делегат. Это может помочь в ваших расследованиях.

javax / WS / RS / внутр / RuntimeDelegate.java