2012-08-11 19 views
9

Tôi có một hộp thoại tiến trình mà tôi sử dụng cho một phần trong chương trình của mình. chương trình xuất hiện như thể nó bị đóng băng. Trong số onPostExecute của tôi AsyncTask Tôi bỏ qua hộp thoại.Hộp thoại tiến trình UI đóng băng/Slow

Tại sao điều này xảy ra vì tôi đang thực hiện tất cả công việc trong nền?

đây là mã của tôi

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(); 
    } 

} 

UPDATE: chạy qua các mã trong chế độ gỡ lỗi đêm qua nó có vẻ bắt đầu để làm điều đó trong vòng lặp for nhưng vẫn tất cả điều này được thực hiện trong một riêng biệt sợi và tôi chỉ đang chèn giá trị vào cơ sở dữ liệu của tôi

UPDATE 2 nếu tôi nhận xét ra các vòng lặp for hộp thoại tiến trình được hiển thị cho ít hơn một giây như vậy mặc dù tôi đang làm tất cả mọi thứ trong một AsyncTask các đoạn chèn vẫn phải chạy trong chuỗi giao diện người dùng

+0

Bạn làm điều này trên sợi chính hoặc sợi ui. Có những chủ đề khác về điều này trên SO, có lẽ họ sẽ giúp đỡ. http: // stackoverflow.com/questions/3652560/what-is-the-android-uithread-ui-thread –

+0

cũng như bạn có thể thấy nó là một AsyncTask vì vậy nó sẽ nằm trong một chủ đề khác – tyczj

+0

trong đó phần 'onPreExecute' của bạn là gì? Ngoài ra, bạn có thể đặt tất cả mã trong 'doInBackground' vào một phương thức vì tất cả nó nên được thực thi trong luồng mới, và làm cho tất cả điều này dễ đọc hơn. Ngoài ra bạn đang thử phần cứng nào? –

Trả lời

2

đặn nó ra, tôi đã là một phương pháp runaway đi trên thread UI mà tôi không để ý

0

Bạn đang sử dụng sai số ProgressDialog.

Bạn cần thêm phương thức onPreExecute và tại đó bạn xác định và hiển thị ProgressDialog. Sau đó, doInBackground được thực hiện trên một chuỗi khác và cuối cùng trong onPostExecute bạn loại bỏ hộp thoại.

Dưới đây là một ví dụ đơn giản:

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(); 

Bằng cách này, tôi cũng khuyên bạn không nên sử dụng các chuỗi mã hóa cứng. Thay vào đó, bạn có thể truy cập tệp strings.xml dưới res\values\ và xác định chuỗi. Sau đó, trong mã của bạn, bạn có thể sử dụng getString(R.string.yourStringId) hoặc R.string.yourStringId. Nó phụ thuộc vào phương thức chấp nhận Id hay không (Phương thức chấp nhận Id, thực sự thực hiện getString với Id bạn đã gửi).

+0

Nhưng sự khác biệt gì nếu tôi sử dụng 'onPostExecute' hoặc chỉ khai báo hộp thoại tiến trình ngay trước khi tôi khởi động AsyncTask? Tôi chỉ không thấy làm thế nào mà sẽ sửa chữa vấn đề kể từ khi cả hai đều trong thread UI đúng? – tyczj

+0

@tyczj Tôi thành thật không biết sự khác biệt chính xác (nhưng bằng cách nói điều này, bạn đang tăng câu hỏi tại sao 'onPostExecute' là cần thiết ở tất cả). Dường như có sự khác biệt, bởi vì tôi có cùng một vấn đề mà bạn đang gặp phải. Tôi cũng đã định nghĩa 'ProgressDialog' ra khỏi AsyncTask, và khi tôi chuyển vào bên trong, nó hoạt động hoàn toàn trơn tru. Tôi đề nghị bạn thử nó và xem. Nó sẽ làm việc –

+0

Tôi đã ném nó trong onPreExecute và nó vẫn làm điều tương tự tiếc là – tyczj

0

Tôi đã triển khai hộp thoại theo cách này thành công.

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; 
     } 
} 
0

tôi không thấy bất kỳ lỗi trong mã của bạn, nhưng bạn phải hiểu rằng chỉ viết mã trong chủ đề khác không có nghĩa là nó sẽ nhận được bộ xử lý khác. nếu thiết bị của bạn có bộ xử lý lõi đơn thì nó sẽ cắt thời gian và hoạt động theo cách vòng tròn. nếu thiết bị của bạn có nhiều lõi, nó sẽ thực hiện nhiều luồng thực tế. vì vậy nếu bạn có bộ xử lý lõi đơn, nó sẽ hiển thị cho bạn một số độ trễ trong thanh tiến trình.

+0

tất cả các thiết bị được thử nghiệm có nhiều lõi – tyczj

1

Điều này có thể xảy ra vì chuỗi nền của bạn tiêu thụ 100% CPU thiết bị. Khi CPU bận xử lý một luồng, chuỗi giao diện người dùng sẽ không được cập nhật và do đó bạn thấy nó bị đóng băng

Cố gắng phát hiện hoạt động tích cực nhất bằng cách xóa các phần mã khỏi doInBackground của bạn và chạy lại ứng dụng. Cũng cố gắng để xem cách nó thực hiện khi thiết bị không cắm qua cổng USB - điều này một vài lần cung cấp kết quả kỳ lạ

+0

vấn đề nằm trong vòng lặp mà nó chèn các trường vào cơ sở dữ liệu của tôi. Nếu tôi nhận xét rằng nó cho thấy hộp thoại tiến trình trong ít hơn một giây vì vậy rõ ràng mặc dù tôi đang làm tất cả mọi thứ trong một 'AsyncTask' chèn vẫn phải chạy trong thread UI – tyczj