进度对话框UI冻结/慢

我有一个进度对话框,我用在我的程序中的一部分,我在后台做了一个时间密集的操作,但是当对话框显示时,UI或微调器图标冻结/慢/犹豫,使程序看起来好像冻结了。 在我的AsyncTask onPostExecute我closures对话框。

为什么会发生这种情况,因为我在后台做所有的工作?

这是我的代码

 pDialog = ProgressDialog.show(FullGame.this,"Starting New Game","Please Wait...", true); new StartNewGame().execute(); private class StartNewGame extends AsyncTask<Void,Void,Boolean>{ @Override protected Boolean doInBackground(Void... params) { try{ ContentValues values = new ContentValues(); Cursor c = getContentResolver().query(Games.PART1_URI,new String[] {Games.PART1_NUM}, Games.PART1_GAME_ID+"="+gameID+" AND "+Games.PART1_FRAME_NUM+"="+10,null,null); c.moveToFirst(); String num = c.getString(0); int part1 =0; if(num.equals("-")){ part1=0; }else{ part1=Integer.parseInt(num); } c = getContentResolver().query(Games.PART2_URI,new String[] {Games.PART2_NUM}, Games.PART2_GAME_ID+"="+gameID+" AND "+Games.PART2_FRAME_NUM+"="+10,null,null); c.moveToFirst(); int part2 = 0; if(num.equals("-")){ part2=0; }else{ part2=Integer.parseInt(num); } c = getContentResolver().query(Games.PART3_URI,new String[] {Games.PART3_NUM}, Games.PART3_GAME_ID+"="+gameID,null,null); c.moveToFirst(); int part3 = 0; if(num.equals("-")){ part3=0; }else{ part3=Integer.parseInt(num); } if(part1 == 10){ values.clear(); values.put(Games.STRIKES_FRAME_NUM,10); values.put(Games.STRIKES_BOWLER_ID,bowlerClickedID); values.put(Games.STRIKES_GAME_ID,gameID); getContentResolver().insert(Games.STRIKES_URI, values); } if(part2 == 10){ values.clear(); values.put(Games.STRIKES_FRAME_NUM,10); values.put(Games.STRIKES_BOWLER_ID,bowlerClickedID); values.put(Games.STRIKES_GAME_ID,gameID); getContentResolver().insert(Games.STRIKES_URI, values); } if(((part2+part3) == 10) && !score.checkSpare(10)){ values.clear(); values.put(Games.SPARES_BOWLER_ID,bowlerClickedID); values.put(Games.SPARES_FRAME_NUM,10); values.put(Games.SPARES_GAME_ID,gameID); getContentResolver().insert(Games.SPARES_URI, values); } if(part3 == 10){ values.clear(); values.put(Games.STRIKES_FRAME_NUM,10); values.put(Games.STRIKES_BOWLER_ID,bowlerClickedID); values.put(Games.STRIKES_GAME_ID,gameID); getContentResolver().insert(Games.STRIKES_URI, values); } c.close(); }catch(Exception e){ Log.d("FullGame",e.toString()); } Date date = new Date(System.currentTimeMillis()); DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); String newDate = df.format(date); ContentValues values = new ContentValues(); values.put(Games.GAMES_BOWLER_ID,bowlerClickedID); values.put(Games.GAMES_TEAM_ID,1); values.put(Games.GAMES_DATE,newDate); values.put(Games.GAME_SEASON, pref.getLong(Preferences.SELECTED_SEASON, 1)); values.put(Games.GAMES_TOURNAMENT_ID, tournamentID); Uri uri = getContentResolver().insert(Games.GAMES_URI, values); gameID = ContentUris.parseId(uri); int gameid = Integer.valueOf(String.valueOf(gameID)); values.clear(); Cursor cName = getContentResolver().query(BowlersDB.CONTENT_URI,new String[] {BowlersDB.FIRST_NAME},BowlersDB.ID+"="+bowlerClickedID,null,null); cName.moveToFirst(); String name = cName.getString(0); for(int i = 0;i<10;i++){ int num = i+1; values.put(Games.NAMES_FRAME_NUM,num); values.put(Games.NAMES_GAME_ID,gameid); values.put(Games.NAMES_NAME,name); getContentResolver().insert(Games.NAMES_URI, values); names(i,name); values.clear(); values.put(Games.PART1_FRAME_NUM,num); values.put(Games.PART1_NUM,"0"); values.put(Games.PART1_GAME_ID,gameid); getContentResolver().insert(Games.PART1_URI, values); values.clear(); values.put(Games.PART2_FRAME_NUM,num); values.put(Games.PART2_NUM,"0"); values.put(Games.PART2_GAME_ID,gameid); getContentResolver().insert(Games.PART2_URI, values); values.clear(); values.put(Games.TOTALS_FRAME_NUM,num); values.put(Games.TOTALS_FRAME_TOTAL,"0"); values.put(Games.TOTALS_GAME_ID,gameid); getContentResolver().insert(Games.TOTALS_URI, values); values.clear(); values.put(Games.POCKETS_BOWLER_ID,bowlerClickedID); values.put(Games.POCKETS_FRAME_NUM,i); values.put(Games.POCKETS_GAME_ID,gameID); values.put(Games.POCKETS_TEAM_ID, teamSelectedID); values.put(Games.POCKETS_TOURNAMENT_ID, tournamentID); values.put(Games.POCKETS_NUM, 0); values.put(Games.POCKETS_SEASON, pref.getLong(Preferences.SELECTED_SEASON, 1)); getContentResolver().insert(Games.POCKETS_URI, values); values.clear(); } values.put(Games.PART3_GAME_ID,gameid); values.put(Games.PART3_NUM,"0"); getContentResolver().insert(Games.PART3_URI, values); cName.close(); part1Array = new int[10]; part2Array = new int[10]; totalsArray = new int[10]; part3 = 0; mPinsUp = new ArrayList<Long>(); mPinsUp.add((long) 1); mPinsUp.add((long) 2); mPinsUp.add((long) 3); mPinsUp.add((long) 4); mPinsUp.add((long) 5); mPinsUp.add((long) 6); mPinsUp.add((long) 7); mPinsUp.add((long) 8); mPinsUp.add((long) 9); mPinsUp.add((long) 10); return true; } protected void onPostExecute(Boolean result){ pDialog.dismiss(); } } 

更新:昨天晚上在debugging模式下运行的代码似乎开始在for循环中,但仍然是在一个单独的线程中完成,我只是将值插入到我的数据库

更新2,如果我注释掉for循环进度对话框显示不到一秒钟,所以即使我正在做一切AsyncTask插入必须仍然运行在UI线程

Related of "进度对话框UI冻结/慢"

想通了,我有一个失控的方法进行的UI线程,我没有注意到

这可能是因为你的后台线程消耗了100%的设备CPU。 当CPU忙于处理一个线程时,UI线程将不会更新,因此您将其视为冻结

尝试通过从doInBackground中删除部分代码并再次运行应用程序来检测最积极的操作。 当设备没有通过USB插入时,也尝试看看它是如何执行的 – 这有时会提供奇怪的结果

您正在使用ProgressDialog错误。

您需要添加一个onPreExecute方法,并在那里定义并显示您的ProgressDialog 。 然后在另一个线程上执行doInBackground ,最后在onPostExecuteclosures对话框。

这是一个简单的例子:

 class RefreshChanges extends AsyncTask<String, Void, String> { private ProgressDialog mProgressDialog = new ProgressDialog( mContext); @Override protected void onPreExecute() { mProgressDialog.setTitle("Whatever title"); mProgressDialog.setMessage("Whatever message"); mProgressDialog.show(); } protected String doInBackground(String... strings) { // Do whatever processing you want... return ""; } protected void onPostExecute(String result) { mProgressDialog.dismiss(); mProgressDialog = null; } } new RefreshChanges().execute(); 

顺便说一句,我也build议你不要使用硬编码的string。 相反,您可以转到res\values\下的strings.xml文件并定义一个string。 然后在你的代码中,你可以使用getString(R.string.yourStringId)R.string.yourStringId 。 它取决于该方法是否接受Id的方法(接受Id的方法,实际上是通过发送它的Id来执行getString )。

我没有看到你的代码中有任何错误,但你必须明白,只有在另一个线程写代码并不意味着它会得到另一个处理器。 如果您的设备使用单核处理器,则它会进行时间分片,并以循环方式工作。 如果您的设备具有多个内核,则会执行实际的多重线程。 所以如果你有单核心处理器,它会显示你进度条上的一些滞后。

我用这种方式成功地实现了对话。

 private ProgressDialog progress; private class AsynTask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { progress = ProgressDialog.show(context, "", "Please wait...", true); } @Override protected void onPostExecute(Void params) { if (progress.isShowing()) progress.dismiss(); } @Override protected Void doInBackground(Void... arg0) { // Do some work return null; } }