Java函数返回空字符串

3

我正在尝试使用jsoup在Java中解析来自服务器的数据。我编写了一个新的函数,它应该以字符串格式返回数据,但它返回空字符串。以下是我的代码:

public String doc;

public String pare(final String url){
        Thread downloadThread = new Thread() {
            public void run() {
                try {
                    doc = Jsoup.connect(url).get().toString();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        downloadThread.start();
        return  doc;
}
4个回答

2

在线程有机会添加任何数据之前,您立即返回文档对象,因此返回空值应该不足为奇。您无法以这种方式返回线程化信息,而需要使用某种类型的回调机制,通知您线程何时完成并准备好消耗数据。


当我在Jsoup.connect(url).get().toString()后添加Log.i("info",doc);时,它会返回我的数据。我应该使用什么回调机制? - user47823
1
那是因为你正在与下载相同的线程上执行它。你需要研究一下线程是什么以及它是如何工作的。 - Gabe Sechan
1
@user47823:正如Gabe所说的那样。至于回调机制,我不做Android,所以我不知道该环境下的标准是什么。如果这是我的非Android代码,我可以使用任何观察者类型的设计模式,例如使用添加到线程类的PropertyChangeListenerSupport对象以及为同一类添加和删除PropertyChangeListener方法,然后在方法完成时调用支持对象上的propertyChange方法。 - Hovercraft Full Of Eels

1
在安卓平台上,你不应该要求Jsoup为你下载任何内容。在底层,Jsoup使用了HttpUrlConnection。这个类非常慢且有一些已知问题。相反,请使用更快的替代方案:Volley
以下是利用Volley的函数示例代码。在下面的示例代码中,我使用了CountDownLatch来等待数据。
private static RequestQueue myRequestQueue = null;

public String pare(final String url) throws Exception {   
   final String[] doc = new String[1];
   final CountDownLatch cdl = new CountDownLatch(1);

   StringRequest documentRequest = new StringRequest( //
        Request.Method.GET, //
        url, //
        new Response.Listener<String>() {
           @Override
           public void onResponse(String response) {
               doc[0] = Jsoup.parse(response).html();
               cdl.coutDown();
           }
        }, //
        new Response.ErrorListener() {
           @Override
           public void onErrorResponse(VolleyError error) {
               Log.e("MyActivity", "Error while fetching " + url, error);
           }
        } //
   );

   if (myRequestQueue == null) {
       myRequestQueue = Volley.newRequestQueue(this);
   }

   // Add the request to the queue...
   myRequestQueue.add(documentRequest);

   // ... and wait for the document.
   // NOTA: User experience can be a concern here. We shouldn't freeze the app...
   cdl.await();

   return doc[0];
} 

如果我运行这段代码,它会创建一个空白屏幕,应用程序也停止响应,我做错了什么? - user47823
@user47823,你正使用的线程被cdl.await()锁定,因此应用无响应。在另一个线程中调用pare函数。 - Stephan

0
在return语句之前添加downloadThread.join()。这将等待线程完成并将响应放入doc中。但是:这样做会失去所有异步执行的好处,它的行为与您编写的代码相同:
public String pare(final String url){
    return Jsoup.connect(url).get().toString();
}

准确地说,您会失去使用线程的所有好处。 - Hovercraft Full Of Eels
如果我运行这段代码,将会出现以下错误:Unable to start activity android.os.NetworkOnMainThreadException - user47823

0

我想使用jsoup... - user47823
那么你应该尝试一下这个教程:http://www.survivingwithandroid.com/2014/04/parsing-html-in-android-with-jsoup-2.html - Arshad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接