我正在做一个Android项目。 我有线程问题。我想在按下主页按钮时暂停线程,并在返回应用程序时恢复它。
这是我的代码:
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
int tempWaktu = (Integer) msg.obj;
if(!status){
if(tempWaktu < 10 ) textSec.setText("0"+tempWaktu);
else textSec.setText(""+tempWaktu);
}
if(tempWaktu==0){
stopYourActivity();
}
}
}; //handler
@Override
public void onStart()
{
super.onStart();
timer = new Thread(new Runnable() {
public void run() {
try
{
while(jalan){
if(running){
Thread.sleep(1000);
waktu--;
Message msg = handler.obtainMessage(1, waktu);
handler.sendMessage(msg);
if(waktu==0){
running = false;
}
}
}
}
catch (Throwable t){
}
}//run
});//background
timer.start();
}//onStart
@Override
public void onPause(){
synchronized (timer) {
try {
timer.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
pause = true;
}
@Override
public void onResume(){
super.onResume();
if(pause){
synchronized (timer) {
timer.notify(); textSec.postInvalidate();
pause = false;
}
}
}
当我按下主页按钮时,线程不会停止,当我回到应用程序时,UI会冻结。我不明白为什么。
我需要的是当我按下主页按钮时线程暂停,当我回复线程运行且UI没有冻结时。
我感谢你写的任何代码来帮助我。非常感谢你。
更新
我已将timer.wait()
放在run()
内,如下所示:
@Override
public void onStart()
{
super.onStart();
if(!pause){
timer = new Thread(new Runnable() {
public void run() {
try
{
while(jalan){
if(running){
Thread.sleep(1000);
waktu--;
Message msg = handler.obtainMessage(1, waktu);
handler.sendMessage(msg);
Log.v("Timer Thread", "Thread Berjalan "+waktu);
if(waktu==0){
Log.v("Thread Timer", "Waktu Berhenti");
running = false;
}
if(pause){
synchronized (timer) {
timer.wait();
}
}
}
}
}
catch (Throwable t){
}
}//run
});//background
timer.start();
}
}//onStart
和timer.notify()
就像上面的onResume()
一样,当我按下它时,它会转到强制关闭。这是日志说:
07-19 10:27:41.173: E/AndroidRuntime(2280): FATAL EXCEPTION: main
07-19 10:27:41.173: E/AndroidRuntime(2280): android.app.SuperNotCalledException: Activity {com.konsep.baby.scratch/com.konsep.baby.scratch.BabyScratchChallenge} did not call through to super.onPause()
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.Activity.performPause(Activity.java:3854)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1191)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2341)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2291)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread.access$1700(ActivityThread.java:117)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:938)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.os.Handler.dispatchMessage(Handler.java:99)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.os.Looper.loop(Looper.java:123)
07-19 10:27:41.173: E/AndroidRuntime(2280): at android.app.ActivityThread.main(ActivityThread.java:3683)
07-19 10:27:41.173: E/AndroidRuntime(2280): at java.lang.reflect.Method.invokeNative(Native Method)
07-19 10:27:41.173: E/AndroidRuntime(2280): at java.lang.reflect.Method.invoke(Method.java:507)
07-19 10:27:41.173: E/AndroidRuntime(2280): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-19 10:27:41.173: E/AndroidRuntime(2280): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-19 10:27:41.173: E/AndroidRuntime(2280): at dalvik.system.NativeStart.main(Native Method)
我的代码出了什么问题?
答案 0 :(得分:1)
第一个问题是Activity
的生命周期实际上是如何工作的。当您转到主屏幕时,您当前的Activity
会一直进入停止状态(即onStop()
被调用)。因此,当您返回应用程序时,您将收到onStart()
,然后onResume()
。现在,让我们根据这些信息检查代码中发生的情况:
onStart()
中创建一个新线程并启动。 onResume()
由于布尔标志而无效。onPause()
,在此线程上调用wait()onStart()
,现在计时器指向一个新线程,让你的旧线程悬空。onResume()
并将notify()
发送到新的Thread实例。所以这里的问题是你wait()
的主题和你notify()
的主题不是同一个主题。
第二个问题是wait()
实际上做了什么。从Java文档(重点添加):
使调用线程等到另一个线程调用此对象的notify()或notifyAll()方法。此方法只能由拥有此对象监视器的线程调用;请参阅notify(),了解线程如何成为监视器的所有者。
在wait()
上调用Thread
不会阻止创建Thread
,它会阻止调用方法的线程,在本例中为主线程。所以你编写了一个在暂停期间成功阻止主线程的应用程序,无法解锁它,因此冻结。
如果要使用wait()
和notify()
来暂停后台线程,则需要确保从后台线程中调用wait()
(即在{{1}内部阻止)
答案 1 :(得分:0)
Google的培训页面已经解释过。Here
当您的应用暂停时,它会“停止动画或其他可能消耗CPU的动作。”