2016-03-12 143 views
2

我想解析從我的服務器在Java Java與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; 
} 

回答

1

Android平臺上,你不應該問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]; 
} 
+0

如果我運行此代碼它會創建一個blanl屏幕,並且應用程序停止響應,我做錯了什麼? – user47823

+0

@ user47823您正在使用的線程被'cdl.await()'阻止,這就是應用程序停止響應的原因。在另一個線程中調用'pare'。 – Stephan

2

您傳回doc對象立即,線程有機會對任何數據添加到它之前,所以應該是毫不奇怪,這將返回空。您不能以這種方式返回線程信息,而是需要使用某種類型的回調機制,一種在線程完成時以及數據準備就緒時可以通知您的回調機制。

+0

當我把Log.i(「info」,doc);在Jsoup.connect(url).get()。toString()之後它返回我的數據。我應該使用什麼回撥機制? – user47823

+1

這是因爲你在與下載相同的線程上執行它。你需要研究一個線程是什麼以及它是如何工作的。 –

+1

@ user47823:與Gabe狀態完全相同。至於回調機制,我沒有做Android,所以我不知道這個環境的標準是什麼。如果這是我的非android代碼,那麼我可以使用任何觀察者類型設計模式來完成此操作,例如添加到線程類中的PropertyChangeListenerSupport對象,以及爲同一個類添加和刪除PropertyChangeListener方法,然後調用propertyChange方法該方法已完成時的支持對象。 –

0

的網絡調用return語句添加downloadThread之前。加入()。這將等到線程完成並將響應放入文檔中。但是:這樣做你將失去從異步執行的所有好處,它的表現爲你只是將代碼都是完全相同:

public String pare(final String url){ 
    return Jsoup.connect(url).get().toString(); 
} 
+0

確切地說 - 你失去了使用線程的所有好處。 –

+0

如果我運行此代碼,我收到此錯誤:'無法啓動活動android.os.NetworkOnMainThreadException' – user47823