1

ユーザーがスタートボタンを押すと、データ収集の機能が開始されるAndroidアプリがあります。このすべてのプロセスにかかった時間を示し、ユーザーが停止を押すまで毎秒更新されるカスタム EditText があります。以下のような AsyncTask を使用してこれを実装しました。

    protected class RecTimer extends AsyncTask<Context, Integer, String> 
    {
                @Override
                protected String doInBackground( Context... params ) 
                {
                         int sec=00;
                     int min=00;
                     int hours=00;
                     timerdata=timer.split(":");
                     hours=Integer.parseInt(timerdata[0]);
                     min=Integer.parseInt(timerdata[1]);
                     sec=Integer.parseInt(timerdata[2]);

                        while(Recording==true) 
                        {
                            try{

                                        Thread.sleep( 1000 );
                                        publishProgress( sec , min , hours );
                                        sec++;

                                        if(sec==60){

                                            min++;
                                            sec=0;

                                            if(min==60){
                                                hours++;
                                                min=0;
                                            }
                                        }
                                } catch( Exception e ){
                                        Log.i("makemachine", e.getMessage() );
                                }
                        }
                        return "COMPLETE!";
                }

                @Override
                protected void onPreExecute() 
                {
                        Log.i( "makemachine", "onPreExecute()" );
                        super.onPreExecute();                   
                }

                @Override
                protected void onProgressUpdate(Integer... values) 
                {
                        super.onProgressUpdate(values);
                        //Log.i( "makemachine", "onProgressUpdate(): " +  String.valueOf( values[0] ) );

                        String format = String.format("%%0%dd", 2);
                        String Sec = String.format(format, values[0]);
                        String Min = String.format(format, values[1]);
                        String Hours = String.format(format, values[2]);

                        ((EditText) findViewById(R.id.duration1)).setText(Hours + ":"+ Min + ":" + Sec);

                }


                @Override
                protected void onPostExecute( String result ) 
                {      
                        super.onPostExecute(result);
                        Log.i( "makemachine", "onPostExecute(): " + result );

               }          
        } 

最初は問題なく動作しているように見えましたが、アプリがアイドル状態でフォーカスが合っていない場合、タイマーが常に適切にカウントされない場合があることがわかりました。たとえば、デバイスを 15 分間放置した後、「時計」で 5 分間しか経過していないことがわかります。ビューがフォーカスに戻ったので、すべてが再び正常に機能しているようです。

そもそもなんでこうなるの?AsyncTask は常にバックグラウンドで実行されるべきではありませんか? これを実装するために使用する必要がある他のより良いアプローチはありますか?

事前にみんなに感謝します!

編集: TrackRuler のおかげで、次のように実装しました。

プライベート Runnable Timer = new Runnable() {

  public void run() {
           long current = SystemClock.uptimeMillis();
               String format = String.format("%%0%dd", 2);
               timerdata=timer.split(":");
               sec++;

               if(sec==60){

                   min++;
                   sec=0;

                   if(min==60){
                       hours++;
                       min=0;
                   }
               }

               String Sec = String.format(format, sec);
               String Min = String.format(format, min);
               String Hours = String.format(format, hours);

               ((EditText) findViewById(R.id.duration1)).setText(Hours + ":"+ Min + ":" + Sec);


                   TimerHandler.postAtTime(this,
                          current +  1000);
                    }                       
            }; 

私のメイン コードから、ハンドラーから呼び出します: TimerHandler.post(Timer);

今では動作します.Runnable(?)内のビューの更新に問題があるかどうか知りたいだけです

4

2 に答える 2

1

私が実装したのはこのようなものです、

protected class RecTimer extends AsyncTask<Context, Integer, String> 
    {
                @Override
                protected String doInBackground( Context... params ) 
                {
                   //ToDO........
                     new Thread(new Timer(CurrentActivity.this)).start();
                   //ToDO........
                }

                @Override
                protected void onPreExecute() 
                {
                   //ToDO........     
                }

                @Override
                protected void onProgressUpdate(Integer... values) 
                {
                    //ToDO........   
                }


                @Override
                protected void onPostExecute( String result ) 
                {      
                    //ToDO........
               }          
        } 

そして、これはDBの更新に適していると思います。ただし、UI の更新については、UI スレッドに影響があるかどうかを確認してください。これでうまくいきました。マスターがこの質問に答えるのを待ってください。また、私はあなたを助けようとします...

于 2012-04-16T11:23:49.000 に答える
1

基本的に AsyncTask は while が完了すると終了します。スリープコールを待ちません。

インターフェイスを実装しRunnable、「Runnable」内で必要なことを行う必要がある場合があります。

于 2012-04-16T09:37:56.193 に答える