2017-07-31 55 views
1

我是AsyncTask中的新手,並且出現問題。 我有AsyncTask,它通過調用另一個類的函數將信息保存在數據庫中。問題是onPostExecute方法在我的函數完成之前調用;這裏是我的代碼:如何等待asynctask中另一個類的方法在android中完成

class checkNewReviews2 extends AsyncTask<List<ReviewList.ReviewItem>, Void, Void>{ 


    @Override 
    protected Void doInBackground(List<ReviewList.ReviewItem>... reviewList) { 

     int size = reviewList[0].size(); 
     if(size>0) { 

      for (int i = 0; i < size; i++) { 
       ReviewList.ReviewItem r = reviewList[0].get(i); 
       ContentValues c = new ContentValues(); 
       c.put(LentaClass.LentaListEntry.FILM_ID, r.getFilm_id()); 
       c.put(LentaClass.LentaListEntry.USER_ID, r.getUser_id()); 
       c.put(LentaClass.LentaListEntry.REVIEW_TEXT, r.getReview_text()); 
       c.put(LentaClass.LentaListEntry.CREATED_AT, r.getCreated_at()); 
       c.put(LentaClass.LentaListEntry.REVIEW_TYPE, r.getReview_type()); 
       c.put(LentaClass.LentaListEntry.VIEWS, r.getViews()); 
       sqLiteDatabase.insert(LentaClass.LentaListEntry.TABLE_NAME, null, c); 

       c.clear(); 
      } 
      FilmHandler filmHandler = new FilmHandler(getContext()); 
      filmHandler.HandleFilms(reviewList[0]); 
      UserHandler userHandler = new UserHandler(getContext()); 
      userHandler.HandleUsers(reviewList[0]); 


     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

     initiateRecyclerView(); 
    } 
} 

我已經嘗試將所有調用放入onPreExecute,但結果仍然相同。另外作爲通知,第一塊sql代碼(循環)成功處理,而不是作爲電影和用戶處理程序。 AsyncTask完全執行後應該如何調用initiateRecyclerView?

+1

'的問題是,onPostExecute方法是我的功能finishes'之前,也許你正在使用其他線程的從'doInBackground' workThread –

+2

onPostExecute只會doInBackground完成後執行調用。如果FilmHandler和Userhandler是在單獨的線程上實現的,則可能會導致此問題。因此,爲避免這種情況,請勿使用另一個線程將數據保存到數據庫中,而是在doInBackground本身中完成整個保存數據。 –

+0

那麼我怎麼能在同一個線程中運行FilmHandler和UserHandler呢? –

回答

0

您的doInBackgound()方法需要「等待」您的FilmHandlerUserHandler類才能完成。

我的猜測是,你的類工作在後臺線程,所以當你使用這些代碼立即繼續到return null聲明 - 和整理工作背景,導致onPostExecute()被調用。

更改您的類實現以在調用線程上工作而不是創建它們自己的。

+0

有沒有關於如何實現使用調用線程的任何示例? –

+0

這將是非常具體的方式,超出了我可以在stackoverflow中放置的方式。我建議你從閱讀類的源代碼開始,看看它們使用的異步技術(Thread,AsyncTask等等)。 – mrsegev

0

能否請您添加上下文doinbackground參數作爲well.Might來的getContext返回null /應用程序上下文

0

onPostExecute只會doInBackground完成後執行。如果FilmHandler和Userhandler在單獨的線程上實現,則可能導致此問題。所以爲了避免這種情況,請不要使用另一個線程將數據保存在數據庫中(或)執行其他類型的操作,而是在doInBackground本身中完成整個保存數據。

否則還有另一種方法,您也可以歸檔功能。您需要添加一個回調的filmHandler或userHandler功能,併爲您在doinBackground更新,並在此基礎上,你可以將結果傳遞給PostExcecute()

class checkNewReviews2 extends AsyncTask<List<ReviewList.ReviewItem>, Void, Boolean>{ 


@Override 
protected Void doInBackground(List<ReviewList.ReviewItem>... reviewList) { 

    int size = reviewList[0].size(); 
    if(size>0) { 

     for (int i = 0; i < size; i++) { 
      ReviewList.ReviewItem r = reviewList[0].get(i); 
      ContentValues c = new ContentValues(); 
      c.put(LentaClass.LentaListEntry.FILM_ID, r.getFilm_id()); 
      c.put(LentaClass.LentaListEntry.USER_ID, r.getUser_id()); 
      c.put(LentaClass.LentaListEntry.REVIEW_TEXT, r.getReview_text()); 
      c.put(LentaClass.LentaListEntry.CREATED_AT, r.getCreated_at()); 
      c.put(LentaClass.LentaListEntry.REVIEW_TYPE, r.getReview_type()); 
      c.put(LentaClass.LentaListEntry.VIEWS, r.getViews()); 
      sqLiteDatabase.insert(LentaClass.LentaListEntry.TABLE_NAME, null, c); 

      c.clear(); 
     } 


     FilmHandler filmHandler = new FilmHandler(YourActivity.this); 
     boolean filmHandlerState = filmHandler.HandleFilms(reviewList[0]); 
     UserHandler userHandler = new UserHandler(YourActivity.this); 
     boolean userHandlerState = userHandler.HandleUsers(reviewList[0]); 



     if(filmHandlerState && userHandlerState) 
     { 
     return true; 
     } 
     else 
     { 
     return false; 
     } 
    } 
} 

@Override 
protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

     if(result) 
    { 
     initiateRecyclerView(); 
    } 
    else 
    { 
     // any one of the filmHandler or userHandler function has failed. so do your handling here 

} 

}

在另一點作爲說明通過@ user3413619可能是getContext()返回null,所以,嘗試使其成爲YourActivity.this

+0

我忘了補充說,這段代碼在Fragment中,所以我不能使用Activity.this –

+0

然後你必須添加getActivity()而不是getContext()。試試這個與你的舊代碼 –

+0

我改變了你說的,但問題仍然存在 –

0

make doInBackground方法返回類型布爾值並將結果傳遞給postExecute布爾值然後檢查結果是否true請執行您要調用的方法。

感謝