2017-10-24 1 views
0

Animationを無限に実行する私のアプリケーションにTimerがあります。このように: ユーザーがアプリケーションを使用していない場合にAndroidタイマーを終了する(バックグラウンドでの実行を防止する)

Timer t = new Timer(); 
t.scheduleAtFixedRate(new TimerTask() { 

    @Override 
    public void run() { 
     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       //Running Animation Code 
      } 
     }); 
    } 
}, 1000, 1000); 

は今、私は、ユーザーがアンドロイドの Back Buttonをクリックしても、このコードが実行されることを実現しました。事実、それはバックグラウンドで実行され、それは多くのメモリを使用するようです。

このコードを実行するにはONLY if user in the appが必要です。ユーザーがBack Buttonをクリックすると、このTimerが終了し、ユーザーがHome Buttonをクリックすると、しばらくしてそのユーザーがアプリケーションを使用しないと、Timerが終了します。

私が必要とするのは、メモリを使用しないようにすることです。このコードがしばらく動くと私は気付いたので、Appはフリーズします!私は正常な行動が必要です。

答えて

0

、それがバックグラウンドに置かれます。

このように、onPause()メソッドがトリガされます。

これであなたのアニメーションをキャンセルできます。

@Override protected void onPause() { 
    this.timer.cancel(); 
} 

onResume()メソッドでもアニメーションを開始する必要があります。 onResume()onCreate()の直後にも呼び出されます。コールドアプリの開始からアニメーションを開始するのにも適しています。

@Override protected void onResume() { 
    this.timer.scheduleAtFixedRate(...); 
} 

onPause()アプリから別のアプリケーション(例えば:着メロピッカー)を起動した場合にも呼び出されます。同様に、アプリに戻ると、onResume()がトリガーされます。


onBackPressed()に同じ行のコードを追加する必要はありません。

onStop()またはonDestroy()でアニメーションを停止する際のポイントは何ですか?

すでにonPause()で行ってください。あなたのアプリがバックグラウンドに入ると、アニメーションは既にキャンセルされており、は多くのメモリを使用しません

なぜ私はそのような複雑な答えを参照してください。

0

onBackPressed()またはonDestroy()のように、このようにすることができます。あなたが必要な場合は

if (t != null) { 
    t.cancel(); 
} 

、あなたがonResume()にタイマーを開始し、onStop()でそれをキャンセルすることができ、それは完全にあなたの要件に依存します。

呼び出し元がタイマーのタスク実行スレッド を迅速に終了させたい場合、呼び出し側はタイマーのcancelメソッドを呼び出す必要があります。これは、これを行うには、100%の最良の方法ではないかもしれません、それはいくつかによって悪い習慣と見なされることがあります - Android Timer documentation

またpurgeHow to stop the Timer in android?

0

免責事項が表示されるはずです。

プロダクションアプリで以下のコードを使用しています。私はそれをあなたに非常に良いスタートを与える必要がある基本的なサンプルに(アプリケーションの特定の参照とコードを削除)を編集している。

変数mIsAppVisible変数は、アプリ内の任意の場所(Appクラス)から呼び出すことができ、アプリのフォーカス/視認の必要条件に基づいてコードを実行する必要があるかどうかを確認できます。

あなたは


public class App extends Application { 
    public static boolean mIsAppVisible = false; 


    ... 
} 

など、アプリが実際にインタラクティブであるかどうかを確認するためにParentActivityを拡張し、あなたの活動にmIsAppInBackgroundをも確認することができ、「親」の活動のクラスを作成し、すべてのあなたのこと他の活動も拡大する。あなたがあなたの活動の方法を作成することができますあなたの使用のために

public class ParentActivity extends Activity { 
    public static boolean mIsBackPressed = false; 
    public static boolean mIsAppInBackground = false; 
    private static boolean mIsWindowFocused = false; 
    public boolean mFailed = false; 
    private boolean mWasScreenOn = true; 

    @Override 
    protected void onStart() { 
     applicationWillEnterForeground(); 

     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 

     applicationDidEnterBackground(); 
    } 

    @Override 
    public void finish() { 
     super.finish(); 

     // If something calls "finish()" it needs to behave similarly to 
     // pressing the back button to "close" an activity. 
     mIsBackPressed = true; 
    } 

    @Override 
    public void onWindowFocusChanged(boolean hasFocus) { 
     mIsWindowFocused = hasFocus; 

     if (mIsBackPressed && !hasFocus) { 
      mIsBackPressed = false; 
      mIsWindowFocused = true; 
     } 

     if (!mIsWindowFocused && mFailed) 
      applicationDidEnterBackground(); 

     if (isScreenOn() && App.mIsAppVisible && hasFocus) { 
      // App is back in focus. Do something here... 

      // this can occur when the notification shade is 
      // pulled down and hidden again, for example. 
     } 

     super.onWindowFocusChanged(hasFocus); 
    } 

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

     if (!mWasScreenOn && mIsWindowFocused) 
      onWindowFocusChanged(true); 
    } 

    @Override 
    public void onBackPressed() { 
     // this is for any "sub" activities that you might have 
     if (!(this instanceof MainActivity)) 
      mIsBackPressed = true; 

     if (isTaskRoot()) { 
      // If we are "closing" the app 
      App.mIsAppVisible = false; 
      super.onBackPressed(); 
     } else 
      super.onBackPressed(); 
    } 

    private void applicationWillEnterForeground() { 
     if (mIsAppInBackground) { 
      mIsAppInBackground = false; 
      App.mIsAppVisible = true; 

      // App is back in foreground. Do something here... 

      // this happens when the app was backgrounded and is 
      // now returning 
     } else 
      mFailed = false; 
    } 

    private void applicationDidEnterBackground() { 
     if (!mIsWindowFocused || !isScreenOn()) { 
      mIsAppInBackground = true; 
      App.mIsAppVisible = false; 

      mFailed = false; 

      // App is not in focus. Do something here... 
     } else if (!mFailed) 
      mFailed = true; 
    } 

    private boolean isScreenOn() { 
     boolean screenState = false; 
     try { 
      PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); 

      screenState = powerManager.isInteractive(); 
     } catch (Exception e) { 
      Log.e(TAG, "isScreenOn", e); 
     } 

     mWasScreenOn = screenState; 

     return screenState; 
    } 
} 

(コードスニペットはMainActivityを想定)penguinが提案t.cancel();メソッドを呼び出すためのアニメーションを処理しています。その後、ParentActivity.applicationDidEnterBackground()メソッドに次のように追加することができます。

if (this instanceof MainActivity) { 
    ((MainActivity) this).cancelTimer(); 
} 

それともParentActivityクラスにタイマーを追加しinstanceofチェックや余分な方法を必要としませんでした。あなたのActivityBackStackの最後の要素がある場合は、ホームボタンを押したかのように

関連する問題