10

バックグラウンドで時間のかかる操作を行うプログラムの一部に使用する進行状況ダイアログがありますが、ダイアログが表示されると、UI またはスピナー アイコンがフリーズ/低速/躊躇し、プログラムがフリーズしたように見えます。私onPostExecuteの私の中で私AsyncTaskはダイアログを閉じます。

バックグラウンドですべての作業を行っているのに、なぜこれが起こるのでしょうか?

ここに私のコードがあります

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

}

更新: 昨夜、デバッグ モードでコードを実行すると、for ループで実行を開始するように見えますが、これはすべて別のスレッドで実行され、データベースに値を挿入するだけです

更新 2 for ループをコメントアウトすると、進行状況ダイアログが 1 秒未満表示されるためAsyncTask、挿入ですべてを実行しているにもかかわらず、UI スレッドで実行する必要があります。

4

5 に答える 5

2

気がつかなかった UI スレッドでランナウェイ メソッドが実行されていたことがわかりました。

于 2012-08-17T02:53:38.477 に答える
2

これはおそらく、バックグラウンド スレッドがデバイスの CPU を 100% 消費するために発生します。CPU が 1 つのスレッドの処理でビジー状態の場合、UI スレッドは更新されないため、フリーズしているように見えます

doInBackground からコードの一部を削除し、アプリを再度実行して、最も攻撃的な操作を検出してみてください。また、デバイスが USB 経由で接続されていない場合にどのように動作するかを確認してください - これは時々奇妙な結果をもたらします

于 2012-08-16T12:12:22.890 に答える
0

この方法でダイアログを実装して成功しました。

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;
       }
 }
于 2012-08-16T02:56:01.403 に答える
0

コードに問題はありませんが、別のスレッドでコードを書くだけでは、別のプロセッサを取得するわけではないことを理解する必要があります。デバイスがシングル コア プロセッサを搭載している場合、タイム スライスを実行し、ラウンド ロビン方式で動作します。デバイスに複数のコアがある場合、実際の複数のスレッドが実行されます。そのため、シングル コア プロセッサを使用している場合は、進行状況バーに遅延が表示されます。

于 2012-08-16T11:53:55.797 に答える
0

あなたはProgressDialog間違った使い方をしています。

メソッドを追加する必要がありonPreExecute、そこで を定義して表示しますProgressDialog。その後doInBackground、別のスレッドで実行され、最終的にonPostExecuteダイアログを閉じます。

簡単な例を次に示します。

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

ところで、ハードコーディングされた文字列を使用しないこともお勧めします。代わりに、strings.xml下のファイルに移動しres\values\て文字列を定義できます。次に、コードで、またはのいずれかを使用できgetString(R.string.yourStringId)ますR.string.yourStringId。メソッドが Id を受け入れるかどうかによって異なります (ID を受け入れるメソッドは、実際にgetStringは送信した Id で実行されます)。

于 2012-08-14T14:29:02.637 に答える