Это происходит потому, что вы выполняете вызовы асинхронно. Это означает, что 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
, он должен будет передать интерфейс, который получит заголовок, когда он будет готов, то есть, когда вы фактически получили его из сети.
Ключевой концепцией здесь является то, что вещи являются и должны быть асинхронными, когда речь идет о сетевых запросах / ответах, и обратные вызовы являются одним из способов сделать это.
Существуют и другие методы, такие как реактивные потоки, которые могут перенести работу в другой поток.
редактировать
Функция может быть вызвана с помощью лямбды:
new LoginMethods.Login("url", "account", "pwd", "verify code", (title) -> System.out.println(title));
Если у вас нет лямбд, тогда вы всегда можете создать анонимный класс:
new LoginMethods.Login("url", "account", "pwd", "verify code", new OnTitleReceivedListener() {
public void onTitleReceived(String title){
System.out.println(title);
}
});
Точно так же, как вы сделали для обратных вызовов Retrofit.