- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试为我构建的 Web 服务创建一个简单的 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
我不明白问题出在哪里,因为类似的客户端可以在 PC 上运行。 IP地址没有问题,因为我可以从Android VirtualDevice访问服务器。
Android 版本是 4.0.3 API 版本 15。对于客户端我使用 Jersey 1.11。
编辑
我还尝试使用 EditText 删除整个内容,因为有人告诉我它没有按应有的方式使用。不过,我得到了同样的错误。我根本无法理解我做错了什么。如果我应该显示任何其他附加信息,请告诉我。此外,任何想法都是好的。我是 Android 新手,可能会犯一些愚蠢的错误。
最佳答案
保罗的建议是正确的。我对该主题进行了更深入的研究并找到了原因。
Android apk 打包工具(来自 sdklib.jar 的 APKBuilder 类)在创建包时会忽略不同的文件夹( source )。这些文件夹之一是 META-INF - 无论它是在附加的库中还是在项目的源文件夹中。
Jersey 版本 1.8(可能还有其他版本,但我没有测试过)的解决方法是为 ServiceFinder$ServiceIteratorProvider 提供自定义(默认查找 META-INF/services/,这在 android apk 中不存在)实现具有硬编码的提供程序类名称。我的实现基于 Lucas 提出的 this 实现:
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 < 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 上的验证错误......
注意:这意味着通过此实现,您只能使用 Jersey 支持的 header /类型的子集(我只需要字符串)。要支持其他类型,您必须添加位于 jersey-client.jar 的 META-INF/services 文件夹(或来自 Lucas 的实现)的提供程序,并检查它们是否不会导致 Android 上的验证错误。
上面的代码应该使用如下:
ServiceFinder.setIteratorProvider(new AndroidServiceIteratorProvider());
Client client = Client.create();
编辑:
看来问题出在android-maven-plugin中的fixed。
mosa...@gmail.com 写道:
The pull request with the fix was merged into master and will be released with 3.2.1:
关于android - Android 上的 Jersey 客户端 - NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9342506/
我正在将我的模板代码移植到 XTend。在某些时候,我在测试用例中有这种类型的条件处理: @Test def xtendIfTest() { val obj = new FD if (
我是新来的 kotlin , 当我开始 Null Safety 时,我对下面的情况感到困惑. There's some data inconsistency with regard to initia
我的应用程序一直在各种Android版本中保持良好状态。我有用户在Android 4.3、5.0、5.1和6.0上正常运行。但是,具有S7 Edge的用户刚刚更新了Android 7.0,将文本粘贴到
我使用的是最新版本的 LWUIT (1.5)。我在资源编辑器中设计了我的表单,然后将代码生成到 netbeans。问题是如果我想访问除表单之外的任何对象,我会收到此错误: java.lang.Null
更新: 我在 Fedora 21 上运行它。 SonarQube - 5.0。 SonarQube Runner - 2.4 更新 2:Findbugs v3.1,Java 插件 v2.8 更新3:
RecupData 我的类仅在 web 中返回 NullPointerException。我连接到 pgsql db 8.3.7 - 该脚本在“控制台”syso 中运行良好 - 但引发了测试 Web
我在 mac 上使用 Processing 2.08。我正在尝试使用文档中给出的 createShape 函数创建 PShape。 PShape s; void setup(){ size(500
我在 mac 上使用 Processing 2.08。我正在尝试使用文档中给出的 createShape 函数创建 PShape。 PShape s; void setup(){ size(500
每次运行此 jsp 时,都会收到以下错误异常: org.apache.jasper.JasperException: java.lang.NullPointerException root cause
Kotlin 在编译时有一个出色的 null 检查,使用分离到“可空?”和“不可为空”的对象。它有一个 KAnnotator 来帮助确定来自 Java 的对象是否可以为空。但是,如果 not-null
我有一个布局将显示一个TextView,用于显示一个滴答时间。我遵循了此链接中的代码 How to Display current time that changes dynamically for
Elasticsearch 1.4.1版(“lucene_version”:“4.10.2”) 我有一个像这样的文件: $ curl 'http://localhost:9200/blog/artic
这是我从另一个类调用函数的方法Selenium 设置已定义。 public void Transfer() throws Exception { System.out.println("\nTrans
我试图在主类中使用我在此类中创建的函数,但它崩溃并显示“警告:无法在根 0 处打开/创建首选项根节点 Software\JavaSoft\Prefsx80000002。 Windows RegCrea
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 3 年前。 我有一个 Java 代码,它将
我声明了两张牌: Card card1 = new Card('3', Card.Suit.clubs); Card card2 = new Card('T', Card.Suit.diamonds)
我编写了一段代码来解码 Base64 图像并在 javafx 中表示该图像。在我的 url base64 代码中不断变化。这就是我在 javafx 代码中使用任务的原因。但我收到错误:java.lan
我正在尝试使用 arrayList 的 arrayList 在 Java 中实现图形。 每当调用 addEdge 函数时,我都会收到 NullPointerException 。我似乎无法弄清楚为什么
我是 Java/android 的新手,所以很多这些术语都是外国的,但我愿意学习。我不打算详细介绍该应用程序,因为我认为它不相关。我目前的问题是,我使用了博客中的教程和代码 fragment ,并使我
我正在开发一个 Android 应用程序来在 Android developer guide 的帮助下录制视频.我程序上的所有代码都与此页面相同。 我在 之外定义了权限标签。 当应
我是一名优秀的程序员,十分优秀!