首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >暂停和恢复线程时没有更新UI

暂停和恢复线程时没有更新UI
EN

Stack Overflow用户
提问于 2012-07-19 02:31:59
回答 2查看 3.3K关注 0票数 0

我现在正在做一个android项目。我对里面的线有问题。我想暂停线程时,按下家庭按钮,并继续当回到应用程序。

这是我的密码:

代码语言:javascript
复制
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()里面,就像这样:

代码语言:javascript
复制
@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()中,就像上面一样,当我按下这个家的时候,它就接近了原力。日志上写着:

代码语言:javascript
复制
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)

我的密码怎么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-19 03:04:24

第一个问题是Activity的生命周期是如何工作的。当您进入主屏幕时,您的当前Activity一直到停止状态(即调用onStop() )。因此,当您返回应用程序时,您将收到onStart()然后是onResume()。现在,让我们根据这些信息检查代码中发生了什么:

  1. 在第一次启动时,将在onStart()中创建一个新线程并启动。由于布尔标志,onResume()什么也不做。
  2. 按HOME按钮,调用onPause(),在此线程上调用wait()
  3. 返回到应用程序,调用onStart(),现在计时器指向一个新线程,留下原来的线程悬空。
  4. 调用onResume(),并将notify()发送到新的线程实例。

所以这里的问题是线程wait()notify()线程不是同一个对象。

第二个问题是wait()实际做了什么。来自Java文档(重点是后加的):

导致调用线程,直到另一个线程调用该对象的notifyAll()或notifyAll()方法。此方法只能由拥有此对象监视器的线程调用;有关线程如何成为监视器的所有者,请参见通知()。

wait()上调用Thread并不会阻塞创建Thread的线程,它会阻塞称为方法的线程,在本例中,方法位于主线程中。因此,您已经编写了一个应用程序,该应用程序在暂停期间成功阻止主线程,并且无法解锁它,因此导致冻结。

如果要使用wait()notify()暂停后台线程,则需要确保从后台线程(即在后台线程的run()块内)调用wait()

票数 1
EN

Stack Overflow用户

发布于 2012-07-19 02:41:57

谷歌的培训页面已经解释过了。这里

当你的应用被暂停,它“停止动画或其他正在进行的动作,可能消耗CPU。”

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11553120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档