6

ユーザーがそのアクティビティに遭遇した時間からカウントアップするタイマーがあります

私は現在、onCreate中にクロノメーターセットを使用しています(最初は特定の条件が満たされた場合にのみ開始されます)。しかし、アプリとそのすべてのビューが閉じられるまでクロノメーターがカウントアップし続ける必要があります (それを行うための「終了」機能があります)。

問題は、別のタブを見てそのアクティビティに戻るたびに、クロノメーターがゼロにリセットされることです。(これはoncreateに関係していますが、回避方法はわかりません)

クロノメーターの状態またはカウントアップをバックグラウンドで独自に保存する直感的な方法を見つけられませんでした (または、おそらく自分で時間を追跡し、別の時点でクロノメーターを視覚的に更新する方法が見つかりませんでした)。

私が持っていた 1 つのアイデアは、クロノメーターの現在の時間集計を文字列として使用して、既存のアクティビティ更新でテキストビューを保持しながら、サービスでクロノメーターを開始し、サービスにカウントを継続させることでした。

この問題に対する既知のアプローチに関する洞察をいただければ幸いです。

これはタブホストのアクティビティであり、ビューをロードするたびにタブホストが onPause と onResume の両方を呼び出すため、これはさらに複雑です。これにより、ライフサイクル機能が壊れます。

4

5 に答える 5

6

私のTabhostのせいで、ライフサイクル機能が頼りになりませんでした。

私がしたことは、クロノメーターを中央クラスの静的グローバルにしontabchangedlistener、タブホスト内に を追加して、変更先のタブがクロノメーターのあるタブであるかどうかを確認することでした。これが true の場合、クロノメーターの現在時刻の Long 値が格納されます。

 tabHost.setOnTabChangedListener(new OnTabChangeListener(){

        @Override
        public void onTabChanged(String arg0) {
            // TODO Auto-generated method stub
            if(arg0.contentEquals("homeGroup"))
            {
                //store time in centralhelper.java
                                    //stopWatch is of type Chronometer
                                    //stopWatchLastTime is of type Long and is initially set to zero. Chronometer uses milliseconds to determine time, will never be zero after set
                CentralHelper.stopWatchLastTime = CentralHelper.stopWatch.getBase();
            }
        }

    });

私の homeGroup ビューが読み込まれると、onResume() 関数が呼び出されます。ここには、クロノメーターがカウントを再開する時間を取得するための条件があります。タブホストは通常​​のライフサイクル関数以外のすべてのロードで onPause() と onResume() の両方を呼び出すという事実にもかかわらず、それらはまだ onCreate() の前に呼び出されます。

   public void onResume(){
    super.onResume();

    //update Chronometer with time stored in tabchangelistener
    if(CentralHelper.stopWatchLastTime!=0)
        CentralHelper.stopWatch.setBase(CentralHelper.stopWatchLastTime);
}

これにより、 onCreate() で同様のチェックを行うことができました

    if(CentralHelper.stopWatchLastTime!=0)
    {

        CentralHelper.stopWatch.start(); //this is where it resumes counting from the base set in onResume()
    }
    else
    {
        CentralHelper.stopWatch.start();
        CentralHelper.stopWatch.setBase(SystemClock.elapsedRealtime());
    }
于 2011-10-14T03:00:02.777 に答える
6

時間を持続させる方法はいくつかあります。私が見つけた最も簡単な方法は、 を介して元のアクティビティを作成するために使用されたインテントに時間を保存することgetIntent().putExtra("START_TIME", floatvalue)です。で値を取得できますgetIntent().getFloatExtra("START_TIME", 0f)。このようにすると、次のような多くの利点があります。

  • アクティビティのライフサイクルを壊さず、コンテキストを必要としません。
  • 他のアクティビティとアプリケーションの間で簡単に渡すことができます。
  • 一時停止と停止の間も持続します。
  • 特別なリスナーは必要ありません。
  • 新しいオブジェクトは作成されません (インテントは、アクティビティを初めて作成するために使用されるものです)。

このソリューションは、タブ化されたアクティビティやダイアログなどに永続化するのに最適です。アプリケーションをよりメモリ集約的なものに残す場合、いくつかの制限がありますが、アクティビティが (メモリのために) 破棄された場合のみです。

于 2011-10-11T23:53:09.207 に答える
4

別のアクティビティに切り替えると、前のアクティビティは一時停止されます (添付の画像の onPause など)。アクティビティに戻ったときに再開されますが、dalvik がメモリ不足になると、Activity オブジェクトが削除されることがあります。示しています。

アプリケーション データを Activity インスタンスに保持すると、誤って失われる可能性があります。この Activity Lifecycle http://developer.android.com/reference/android/app/Activity.htmlをお読みください。

ここに画像の説明を入力

于 2011-10-11T15:39:01.207 に答える
4

このアプローチはテストされており、非常にうまく機能します。これを試して:

スレッド (開始/停止) を制御するブール型の揮発性変数を取ります。時間、分、秒のテキスト ビューの 3 つのテキスト ビューを取り、クロノメーターを完全に削除します。Handler次のコードを記述して、UI を更新します。

public void timeUpdate()
{
    timerThread = new Thread(new Runnable() {

        @Override
        public void run() {
            while(continueThread){
                Date newDate = new Date();
                if(((newDate.getTime()) - date.getTime()) > 1000){
                    secondCounter = secondCounter+1;
                    mHandlerUpdateSec.post(mUpdateSec);
                    System.out.println("Inside the Theread ..."+secondCounter);
                    if(secondCounter > 59){
                        minuteCounter = minuteCounter + 1;
                        mHandlerUpdateMinute.post(mUpdateMinute);
                        secondCounter = 0;
                        if(minuteCounter > 59){
                            hourCounter = hourCounter + 1;
                            mHandlerUpdateHour.post(mUpdateHour);
                            minuteCounter = 0;
                        }
                    }
                }
                try{
                    timerThread.sleep(1000);
                }catch (Exception e) {
                    // TODO: handle exception
                }
            }
        }
    });
    timerThread.start();
}

continueThread はブール型の揮発性変数です。false に設定すると、スレッドが停止します。timerThread はスレッドのインスタンスです。時間、分、秒の 3 つのカウンターがあり、最新の時間値が表示されます。ハンドラーは次のように更新されます。

final Handler mHandlerUpdateSec = new Handler();
final Runnable mUpdateSec = new Runnable() {
    public void run() {
        String temp = "" + secondCounter;
        System.out.println("Temp second counter length: " + temp.length());
        if(temp.length() == 1)
            secTextView.setText("0" + secondCounter);
        else
            secTextView.setText("" + secondCounter);
    }
};
final Handler mHandlerUpdateMinute = new Handler();
final Runnable mUpdateMinute= new Runnable() {
    public void run() {
        String temp = "" + minuteCounter;
        System.out.println("Temp second counter length: " + temp.length());
        if(temp.length() == 1)
            minTextView.setText("0" + minuteCounter);
        else
            minTextView.setText("" + minuteCounter);
    }
};
final Handler mHandlerUpdateHour = new Handler();
final Runnable mUpdateHour = new Runnable() {
    public void run() {
        String temp = "" + hourCounter;
        System.out.println("Temp second counter length: " + temp.length());
        if(temp.length() == 1)
            hourTextView.setText("0" + hourCounter);
        else
            hourTextView.setText("" + hourCounter);
    }
};

ここで、タイマーを開始するときはいつでも、continueThread を true に設定して timeUpdate() を呼び出します。停止するには、continueThread = false を実行します。スレッドを再開するには、continueThread を true に設定し、timeUpdate() を再度呼び出します。タイマーを開始/停止するときは、それに応じてカウンターを更新してください。

于 2011-10-14T12:23:51.373 に答える
3

開始時間を共有設定 (またはファイルなど) に保存し、onResume() で (0 から開始するのではなく) そこからカウントアップを確立できます。

理論的には永遠にカウントされる可能性があるため、開始時刻をリセットする必要があるという事実を処理するために、UI にいくつかの変更が必要になる場合があります。

于 2011-10-11T16:19:21.380 に答える