2017-03-18 67 views
-2

我試圖通過從網站上刪除數據來填充RecyclerView。問題是getData()方法SearchCards.java(模型)返回字符串(pageTitle)之前AsyncTask已完成執行導致空字符串。這裏是我的代碼如何僅在AsyncTask的onPostExecute()執行後才返回值?

FragmentOne.java

mAdapter = new SearchAdapter(SearchCards.getData(),this,recyclerView); 
recyclerView.setAdapter(mAdapter); 

SearchCards.java

public static ArrayList<SearchCards> getData() { 

    ArrayList<SearchCards> datatList = new ArrayList<SearchCards>(); 

    String pageTitle = new Scrapping().scrapSubs(); //scrapSubs contains AsynTask      
    String[] yearArr = setYearArr(); 

    for (int i = 0; i < yearArr.length; i++) { 
     SearchCards searchCard = new SearchCards(); 
     searchCard.setYear(yearArr[i]); 
     searchCard.setTitle(pageTitle); //same pagetitle for every year 
     datatList.add(searchCard);    
    }  

    return dataList; 
} 

Scrapping.java

public String ScrapSubs(){ 
    JsoupAsyncTask jsoupAsyncTask = new JsoupAsyncTask(); 
    jsoupAsyncTask.execute(); 
    return pageTitle; 
} 

private class JsoupAsyncTask extends AsyncTask<Void, Void, Void> { 
    @Override 
     protected Void doInBackground(Void... params) { 
      try { 
       htmlDocument = Jsoup.connect(htmlPageUrl).get(); 
       pageTitle = htmlDocument.title(); 
       Log.i(TAG,"PAGETITLE"+pageTitle); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

    @Override 
     protected void onPostExecute(Void result) { 
     //do something 
     } 
} 

如何在Scrapping.java中執行類似返回pageTitle的操作,僅在AsyncTask執行完成後執行。我試過,但沒有奏效:

if(jsoupAsyncTask.getStatus() == AsyncTask.Status.FINISHED){ 
    return pageTitle; 
} 

編輯: 可能這不是一個精心研究的問題。在這裏我找到了我正在尋找的東西:http://stacktips.com/tutorials/android/android-recyclerview-example 我只需要在onPostExecute()中移動SearchAdapter初始化。

+0

'保護無效onPostExecute(虛空結果){// 做something'。不僅是某種東西。但是,例如調用一個修改的getData()並設置你的列表視圖。這是正常的方式。請改編你的設計。你現在所擁有的並不是一帆風順的。 – greenapps

+0

可能的重複http://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a –

+0

感謝您的意見。我對android很陌生並正在嘗試適應。雖然這裏的答案給了我一些清晰的內容。 – mustafa1993

回答

1
private class JsoupAsyncTask extends AsyncTask<Void, Void, You Result Data Type> { 
     @Override 
     protected You Result Data Type doInBackground(Void... params) { 
      try { 
       htmlDocument = Jsoup.connect(htmlPageUrl).get(); 
       pageTitle = htmlDocument.title(); 
       Log.i(TAG,"PAGETITLE"+pageTitle); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return Your Execution Result; 
     } 

     @Override 
     protected void onPostExecute(You Result Data Type Your Execution Result)   { 
     //Do Rest of Your Program 
     } 
} 
0

如果你希望你的代碼運行syncrhonously那麼你不需要使用的AsyncTask在所有 - 只需創建一個方法,做你需要什麼,並調用。 但是,這不會在UI線程中工作 - UI線程方法必須快速返回,否則整個應用程序將停止。 你可能不得不重新考慮你的設計。其中一種方式是展示某種「等待用戶界面」,微調器,進度條等,而AsyncTask在後臺運行,並且只有當數據移動並顯示時才顯示。

+0

我試過沒有AsyncTask。它拋出異常。 https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html – mustafa1993

+0

當然它。你必須瞭解它爲什麼會這樣做,以及爲什麼你的想法不能工作。 – Okas

+0

是的,我現在開始工作了。我之前的做法是錯誤的。現在我直接從我的Fragment類調用AsyncTask.execute(),並在onPostExecute()中初始化RecyclerView。正如你所建議的那樣,我重新考慮了我的設計。 – mustafa1993

0

創建intarface:

private class JsoupAsyncTask extends AsyncTask<Void, Void, Void> { 

    public interface FinishListener { 
     void processFinish(Boolean isFinish); 
    } 

    FinishListener finishListener = null; 

    public JsoupAsyncTask(FinishListener finishListener) { 
     this.finishListener = finishListener; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     try { 
      htmlDocument = Jsoup.connect(htmlPageUrl).get(); 
      pageTitle = htmlDocument.title(); 
      Log.i(TAG, "PAGETITLE" + pageTitle); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     finishListener.processFinish(true); 
     //do something 
    } 
} 

和監聽:

new JsoupAsyncTask(new JsoupAsyncTask.FinishListener() { 
@Override 
public void processFinish(Boolean isFinish) { 
     // do somthing } 
     }).execute(); 
相關問題