2017-07-31 54 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请执行您要调用的方法。

感谢