我的应用中有Timer
无限运行Animation
。像这样:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
//Running Animation Code
}
});
}
}, 1000, 1000);
现在我意识到即使用户单击android的Back Button
,此代码也会运行。如果事实它在后台运行,它似乎使用了大量的内存。
我需要运行此代码ONLY if user in the app
。事实上,当用户点击Back Button
时,此Timer
结束,如果用户点击Home Button
,过了一段时间该用户不使用该应用,则终止此Timer
}。
我需要的是防止使用内存。因为我意识到这段代码运行了一段时间,App冻结了!我需要一个正常的行为。
答案 0 :(得分:0)
你可以在onBackPressed()
或onDestroy()
中这样做,无论你喜欢什么。
if (t != null) {
t.cancel();
}
如果需要,您可以在onResume()
启动计时器并在onStop()
取消计时器,这完全取决于您的要求。
如果调用者想要终止计时器的任务执行线程 很快,调用者应该调用计时器的取消方法。 - Android Timer documentation
答案 1 :(得分:0)
免责声明:这可能不是百分之百的最佳方式,有些人可能认为这是不好的做法。
我在生产应用中使用了以下代码,但它确实有效。然而,我已经将它编辑(删除了应用程序特定的引用和代码)到基本样本中,这应该会给你一个很好的开始。
可以在应用中的任何位置(通过您的mIsAppVisible
类)调用静态App
变量,以检查代码是否应根据应用需要关注/可见的条件运行。< / p>
您还可以检查扩展mIsAppInBackground
的活动中的ParentActivity
,看看该应用是否真的具有互动性等。
public class App extends Application {
public static boolean mIsAppVisible = false;
...
}
创建一个“父”活动类,其他所有活动都会延伸。
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
检查或额外的方法。
答案 2 :(得分:0)
如果Activity
是BackStack
中的最后一个元素,那么它将被置于后台,就像您按下主页按钮一样。
因此,触发了onPause()
方法。
您可以在那里取消动画。
@Override protected void onPause() {
this.timer.cancel();
}
您还应该使用onResume()
方法启动动画。
请注意,onResume()
之后也会调用onCreate()
;所以它甚至适合从冷应用程序启动开始动画。
@Override protected void onResume() {
this.timer.scheduleAtFixedRate(...);
}
如果您从应用中启动另一个应用程序(例如:铃声选择器),也会调用 onPause()
。同样,当您返回应用时,系统会触发onResume()
。
无需在onBackPressed()
中添加相同的代码行。
另外,在onStop()
或onDestroy()
停止动画的重点是什么?
已在onPause()
中执行此操作。当你的应用程序进入后台时,动画将被取消并且不会使用尽可能多的内存。
不知道为什么我会看到如此复杂的答案。