2012-05-17 53 views
0

我正在计算需要一些时间的事情。为此,我已经创建了一个子类的AsyncTask一个内部类:AsyncTask错误困惑

private class AsyncAllPlayAll extends AsyncTask<String, Void, CharSequence> 
{ 
    StournamentDbAdapter mDbHelper; 

    public AsyncAllPlayAll(Context context, StournamentDbAdapter dbHelper) 
    { 
     this.mContext = context; 
     this.mDbHelper = dbHelper; 
    } 

    @Override 
    protected CharSequence doInBackground(String... tournamentRowIds) 
    { 
     Long tournamentRowId = Long.valueOf(tournamentRowIds[0]); 

     Tournament tournament = new Tournament(mDbHelper, tournamentRowId); 
     tournament.setupTournament();    

     Boolean tournamentHasWinner = mDbHelper.winningTournamentParticipantsExists(tournamentRowId); 

     // tournament already run: delete score 
     if(tournamentHasWinner) 
     { 
      mDbHelper.resetTournamentsStocksScore(tournamentRowId); 

      mDbHelper.resetTournamentWinnerStockId(tournamentRowId); 
     } 

     //run tournament! 
     tournament.allPlayAll();     

     TournamentParticipant tournamentParticipant = mDbHelper.insertWinningParticipant(tournamentRowId);      

     populateCompetitorsListView();  

     final CharSequence winner = "Winner is: " + tournamentParticipant.getStock().getName() + "(" + tournamentParticipant.getScore() + ")"; 

     return winner; 
    } 

    @Override        //the winner 
    protected void onPostExecute(final CharSequence result) { 

     super.onPostExecute(result);  

     final int duration = Toast.LENGTH_LONG; 

     TournamentEdit.this.runOnUiThread(new Runnable() { 
      public void run() { 
       Toast.makeText(mContext, "Hello", duration).show(); 
      } 
     }); 

    } 

} 

但我得到一个错误,我不放弃明白了:“不能内螺纹已不叫Looper.prepare创建处理程序()

我在stackoverflow上读了几个线程,但是实现了它们写入的内容并没有改变我的情况。

我确定错误来自于我在onPostExecute中运行的Toast,但这不是问题。该错误发起尝试初始化锦标赛。

Tournament tournament = new Tournament(mDbHelper, tournamentRowId); 

这里是我的筹码:

Thread [<11> AsyncTask #1] (Suspended) 
    FragmentManagerImpl$1.<init>(FragmentManagerImpl) line: 423 
    FragmentManagerImpl.<init>() line: 423 
    Tournament(Activity).<init>() line: 702 
    Tournament.<init>(StournamentDbAdapter, Long) line: 48 
    TournamentEdit$AsyncAllPlayAll.doInBackground(String...) line: 346 
    TournamentEdit$AsyncAllPlayAll.doInBackground(Object...) line: 1  
    AsyncTask$2.call() line: 264  
    FutureTask$Sync.innerRun() line: 305  
    AsyncTask$3(FutureTask).run() line: 137 
    AsyncTask$SerialExecutor$1.run() line: 208 
    ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1076 
    ThreadPoolExecutor$Worker.run() line: 569 
    Thread.run() line: 856 

我tohught它可能是一些问题与分贝线程?当我从主线程传递给AsyncAllPlayAll时。

于是,我就打开内部类的分贝线程(不同的实例),并改变了它的构造函数:

public AsyncAllPlayAll(Context context, StournamentDbAdapter dbHelper) 
    { 
     this.mContext = context; 
     this.mDbHelper = dbHelper; 
     mDbHelper = new StournamentDbAdapter(context); 
     mDbHelper.open(); 
    } 

这并没有帮助:(

现在我尝试添加一个尺蠖(如AsyncTask and Looper.prepare() error建议)

@Override 
    protected CharSequence doInBackground(String... tournamentRowIds) 
    { 
     Looper.prepare(); 
     Long tournamentRowId = Long.valueOf(tournamentRowIds[0]); 

     Tournament tournament = new Tournament(mDbHelper, tournamentRowId); 
     tournament.setupTournament();    

     Boolean tournamentHasWinner = mDbHelper.winningTournamentParticipantsExists(tournamentRowId); 

     // tournament already run: delete score 
     if(tournamentHasWinner) 
     { 
      mDbHelper.resetTournamentsStocksScore(tournamentRowId); 

      mDbHelper.resetTournamentWinnerStockId(tournamentRowId); 
     } 

     //run tournament! 
     tournament.allPlayAll();     

     TournamentParticipant tournamentParticipant = mDbHelper.insertWinningParticipant(tournamentRowId);      

     populateCompetitorsListView();  

     final CharSequence winner = "Winner is: " + tournamentParticipant.getStock().getName() + "(" + tournamentParticipant.getScore() + ")"; 

     Looper.loop(); 

     return winner; 
    } 

代码走得更远,但我得到了以下错误:

引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程可以触及其视图。

现在populateCompetitorsListView()是导致飞机失事的原因,它也清楚为什么:看populateCompetitorsListView()的最后一行,这是

setListAdapter(tournamentStocks); 

试图改变主线程。我将它移到了主类中,这似乎修正了它:计算运行。

@SuppressWarnings("deprecation") 
private void populateCompetitorsListView() 
{ 
    // Get all of the notes from the database and create the item list 
    Cursor tournamentStocksCursor = mDbHelper.retrieveTrounamentStocks(mTournamentRowId); 
    startManagingCursor(tournamentStocksCursor); 

    // Create an array to specify the fields we want to display in the list (only name) 
    String[] from = new String[] {StournamentConstants.TblStocks.COLUMN_NAME, StournamentConstants.TblTournamentsStocks.TBL_COLUMN_TOURNAMENTS_STOCKS_STOCK_SCORE}; 

    // and an array of the fields we want to bind those fields to (in this case just name) 
    int[] to = new int[]{R.id.competitor_name, R.id.competitor_score}; 

    // Now create an array adapter and set it to display using our row 
    SimpleCursorAdapter tournamentStocks = new SimpleCursorAdapter(this, R.layout.competitor_row, tournamentStocksCursor, from, to); 

    //tournamentStocks.convertToString(tournamentStocksCursor); 
    setListAdapter(tournamentStocks);  
} 

但现在的问题是,我似乎被卡住内doInBackground()由于Looper.loop()的执行情况;这是猜测运行无止境的循环?

有没有进一步的想法?

谢谢!

回答

0

经过大量的研究,我发现我的问题是什么:我在doInBackground()&里面使用了太多的代码,然后把大部分代码拿回来放回我的活动中,我的ListView出现了奇怪的行为:它显示了一个空的结果。有时它只显示一行(23)中的结果,有些时候结果不同的行显示。当我运行应用程序 - 我大多没有或只有一行结果。当我使用调试器时 - 我得到的所有结果都很好!怎么来的??? - 嗯 - 我在更新我的主线程上的ListView的错误之前,第二个线程设法用结果更新数据库。所以主线程从数据库中获取了空的结果。我也摆脱了Loop。

我的异步类现在看起来像这样:

private class AsyncAllPlayAll extends AsyncTask<String, Void, Long> 
{ 
    Tournament mTournament = null; 

    public AsyncAllPlayAll(Tournament tournament) 
    { 
     this.mTournament = tournament; 
    } 

    @Override 
    protected Long doInBackground(String... string) 
    { 
     Long ml = null; 
     //run tournament! 
     mTournament.allPlayAll(); 

     return ml = (long) 0; 
    } 

    @Override 
    protected void onPostExecute(Long result) 
    { 
     TournamentEdit.this.runOnUiThread(new Runnable() { 

      public void run() { 
       // TODO Auto-generated method stub 
       populateCompetitorsListView(); 
      } 
     }); 
    } 
} 

正如我现在用runOnUiThread()调用我的主线程中填入方法。我仍然必须更新我的Toast消息,但是我明天会这样做:-)

感谢您阅读这个超长的传奇...