我在OnResponse内分配了一个变量,但似乎无法在OnResponse之外获取其值,如何获得它的值?这是下面的代码。
public class LoginMethods {
public String title, str;
public String Login(String URL, String account, String password, String verifycode){
FormBody formbody = new FormBody.Builder()
.add("TextBox2",password)
.add("txtSecretCode",verifycode)
.add("txtUserName",account)
.build();
Request request=new Request.Builder()
.url(url)
.post(formbody)
.build();
OkHttpClient client2 = new OkHttpClient();
client2.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
str = response.body().string();
}
});
Document doc=Jsoup.parse(str);
title = doc.select("title").first().text();
return title;
}
}
以下是Logcat的一部分:
java.lang.IllegalArgumentException: String input must not be null
at org.jsoup.helper.Validate.notNull(Validate.java:26)
at org.jsoup.parser.TreeBuilder.initialiseParse(TreeBuilder.java:26)
at org.jsoup.parser.TreeBuilder.parse(TreeBuilder.java:42)
at org.jsoup.parser.HtmlTreeBuilder.parse(HtmlTreeBuilder.java:52)
at org.jsoup.parser.Parser.parse(Parser.java:89)
at org.jsoup.Jsoup.parse(Jsoup.java:58)
答案 0 :(得分:0)
发生这种情况是因为您正在异步运行这些调用。这意味着Jsoup.parse(str);
很可能会在通话结束并为str
分配一个值之前发生。
例如,您需要在onResponse
内移动代码并为标题提供回调。这是一个示例:
interface OnTitleReceivedListener {
void onTitleReceived(String title);
}
public class LoginMethods {
public void Login(String URL, String account, String password, String verifycode, OnTitleReceivedListener listener){
FormBody formbody = new FormBody.Builder()
.add("TextBox2",password)
.add("txtSecretCode",verifycode)
.add("txtUserName",account)
.build();
Request request=new Request.Builder()
.url(url)
.post(formbody)
.build();
OkHttpClient client2 = new OkHttpClient();
client2.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
response.body().string();
Document doc=Jsoup.parse(str);
listener.onTitleReceived(doc.select("title").first().text());
}
});
}
现在,呼叫Login
的人都必须传递一个接口,该接口将在标题准备就绪时(即您实际上是从网络上获得的)接收标题。
这里的关键概念是,当涉及到网络请求/响应时,事物应该并且应该是异步的,而回调是做到这一点的一种方法。
其他方法(例如反应式流)也有可能将工作分流到另一个线程。
修改:
然后可以使用lambda调用函数:
new LoginMethods.Login("url", "account", "pwd", "verify code", (title) -> System.out.println(title));
如果您没有lambda,则可以随时创建一个匿名类:
new LoginMethods.Login("url", "account", "pwd", "verify code", new OnTitleReceivedListener() {
public void onTitleReceived(String title){
System.out.println(title);
}
});
就像您对Retrofit回调所做的那样。