2017-03-18 71 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(); 
相关问题