我想从另一个线程返回一个字符串“finalurl”,如下所示:
public String getImageURL(String url) {
final String finalUrl = url;
Thread t1 = new Thread(new Runnable() {
public void run() {
Document doc = null;
try {
doc = Jsoup.connect(finalUrl).get();
} catch (IOException e) {
e.printStackTrace();
}
Element masthead = doc.select("div.post-image").select("img[src~=(?i)\\.(png|jpe?g)]").first();
finalUrl = masthead.absUrl("src");
}
});
t1.start();
return finalUrl;
}
但它不起作用。如何正确使用?
答案 0 :(得分:1)
return finalUrl;
此代码永远不会返回您想要的字符串。
您需要通过众多技术之一修复您的逻辑。最简单的方法是使用处理程序。像这样:
private static final int URL_MESSAGE = 1;
private final Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
super.handleMessage(message);
if (message.arg1 == URL_MESSAGE) {
final Object obj = message.obj;
if (obj instanceof String) {
String url = (String) obj;
}
}
}
};
private final Runnable runnable = new Runnable() {
public void run() {
Document doc = null;
try {
doc = Jsoup.connect(finalUrl).get();
} catch (IOException e) {
e.printStackTrace();
}
Element masthead = doc.select("div.post-image").select("img[src~=(?i)\\.(png|jpe?g)]").first();
String finalUrl = masthead.absUrl("src");
Message message = new Message();
message.arg1 = URL_MESSAGE;
message.obj = finalUrl;
handler.sendMessage(message);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
}
private void execute() {
handler.post(runnable);
}
答案 1 :(得分:1)
对于这种需要,你应该做的是:
Callable
提交给线程池使用Executors
创建您的线程池,例如:
// Create a thread pool composed of only four threads in this case
private final ExecutorService executor = Executors.newFixedThreadPool(4);
以Callable
final Future<String> future = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Document doc = Jsoup.connect(url).get();
Element masthead = doc.select("div.post-image")
.select("img[src~=(?i)\\.(png|jpe?g)]").first();
return masthead.absUrl("src");
}
});
获取结果
try {
return future.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
NB:不能在每次调用时创建线程池,必须为您的所有类创建一次线程池,以便在每次调用时重用它。
答案 2 :(得分:0)
您还没有明确说明您要做什么,但我很确定您不希望您的getImageURL(url)
返回,直到它获得为止一个网址。
正确的方法是不使用线程。
public String getImageURL(String url) {
Document doc = null;
try {
doc = Jsoup.connect(finalUrl).get();
} catch (IOException e) {
throw new RuntimeException(e);
}
Element masthead = doc.select("div.post-image").select("img[src~=(?i)\\.(png|jpe?g)]").first();
return masthead.absUrl("src");
}
如果您认为自己需要在此处使用某个帖子,那么您应该在另一个问题中再次提问,并更详细地解释您尝试做什么以及为什么要这样做做到这一点。
错误说:&#34; 06-18 21:22:12.701 7816-7816 / pl.dariusz.app I / Choreographer:跳过39帧!应用程序可能在其主线程上做了太多工作。&#34;
好的,该错误并不意味着应用程序在一个线程中执行了太多工作。这意味着GUI调用了一个处理函数,并且在处理程序返回之前已经过了 time 。
如果您的事件处理函数没有及时返回,它将阻止您的应用程序及时响应用户下一步做什么。这就是错误信息真正试图告诉你的内容。
你可以通过做&#34;工作&#34;来解决这个问题。在其他一些线程中,如果你的处理程序仍然需要在返回之前等待工作完成。重要的是时间。
解决此类问题的方法是:
你的处理程序将GUI置于某种告诉用户的状态,我等着什么,
然后你的处理程序启动一个等待任何事情的后台任务,(注意:我不是Android程序员,但我很确定那里有更好的方法启动任务而不是创建一个新的裸Thread
个对象。)
然后您的处理程序返回
您的后台任务在其他线程中运行,例如Jsoup.connect(finalUrl).get();
与此同时,如果用户点击某些内容,您的应用仍然可以响应用户输入,即使它只是弹出一条消息,显示,&#34;现在不是,我&# 39;我还在等什么。&#34;
最后,您的后台任务完成,并将其发布到应用程序的事件队列(我还不是Android程序员,所以我实际上并不知道什么方法你打电话来做那件事会更新UI状态,以显示最终发生的事情。