Android:暂停并恢复活动中的线程 [英] Android: Pause and resume a thread within an activity

查看:71
本文介绍了Android:暂停并恢复活动中的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现我在下面描述的内容仅发生在我的仿真设备(Nexus 5,目标api 19,带有Intel Atom(x86)cpu的4.4.2)上,而不发生在我的物理设备上(HTC)一个)....

I've found that what I'm describing below only occurs on my emulated device (Nexus 5, target api 19, 4.4.2 with Intel Atom (x86) cpu), but NOT on my physical device (HTC One)....

Edit1是由于我没有捕获到的IllegalStateException引起的.添加了一些代码以在尝试启动该线程之前检查该线程是否已在运行.这与公认的答案相结合,解决了我的问题.

Edit1 was due to an IllegalStateException that I didnt catch. Added some code to check if the thread was already running before trying to start it. This combined with the accepted answer resolved my issue.

我实现了一个活动,该活动可以在活动的onCreate方法中启动一个新线程,如下所示:

I have implemented an activty that starts a new thread in the activity's onCreate method, like this:

...

private boolean running;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    running = true;
    new Thread(null, work, "myThread").start();
}

Runnable work = new Runnable() {

    @Override
    public void run() { 
        while (running) {
            //Doing work
        }
    }
};

我正在使用活动的onPause方法暂停"我的线程,如下所示:

I'm "pausing" my thread with my activity's onPause method, like this:

@Override
protected void onPause() {
    running = false;
    super.onPause();
}

所以我认为恢复它同样容易...¨

So I thought that resuming it would be just as easy...¨

@Override
protected void onResume(){
    running = true;
    super.onResume();
}

但是我的线程没有恢复.有什么想法吗?感谢您的帮助.

but my thread isn't resuming. Any ideas why? Thankful for any help.

马库斯

推荐答案

我认为所有答案都与您的运行变量有关,因为您无法从中写入和读取变量两个没有synchronized block Threads,所以我发布了自己的答案:

All of the answers i think have some issues about your running variable because you can not write and read a variable from two different Threads without synchronized block so i post my own answer:

package com.example.threadandtoast;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {
    public class MonitorObject{
           public boolean running = true;
           public String message = "";
           public boolean mustBePost = true;
    }

    Thread t;
    int threadNameCounter = 0; // i use this variable to make sure that old thread is deleted 
                               // when i pause, you can see it and track it in DDMS

    Runnable work = new Runnable() {
        boolean myRunning;
        @Override
        public void run() {
            synchronized(mSync) {
               myRunning = mSync.running;
            }
            while (myRunning) {
                runOnUiThread(new Runnable() {  // in order to update the UI (create Toast)
                @Override                       // we must switch to main thread
                public void run() { 
                    // i want to read the message so i must use synchronized block
                    synchronized(mSync) { 
                    // i use this variable to post a message just for one time because i am in an infinite loop
                    // if i do not set a limit on the toast i create it infinite times 
                      if(mSync.mustBePost){       
                          Toast.makeText(MainActivity.this, mSync.message, Toast.LENGTH_SHORT).show();
                          // the message post so i must set it to false
                          mSync.mustBePost = false;
                          // if i am going to pause set mSync.running to false so at the end of infinite loop 
                          //of thread he reads it and leaves the loop
                          if(mSync.message.equals("Main Activity is going to pause")){
                              mSync.running=false;            
                          }
                      }
                    }
                }
               });

            synchronized(mSync) {
               myRunning = mSync.running;
           }
         }
       }
    };

    final MonitorObject mSync = new MonitorObject();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    protected void onPause() {
        super.onPause();
        synchronized(mSync) {
            // mSync.running = false; you can not set it here because 
            // it is possible for the thread to read it and exit the loop before he posts your message
            mSync.mustBePost=true;
            mSync.message = "Main Activity is going to pause";
        }    
    }

    @Override
    protected void onResume(){
       super.onResume();
       threadNameCounter++;
       synchronized(mSync) {
            mSync.running = true;
            mSync.mustBePost=true;
            mSync.message = "Main Activity is going to resume";
        } 
       t = new Thread(work,"My Name is " + String.valueOf(threadNameCounter));
       t.start();
    }

}

或者您可以使用以下代码:

Or you can use this code:

public class MainActivity extends ActionBarActivity {

    Thread t;
    int threadNameCounter = 0; // i use this variable to make sure that old thread is deleted 
                               // when i pause, you can see it in DDMS

    String message = "";
    boolean isPost = false;

    Runnable work = new Runnable() {

        @Override
        public void run() {

            while (true) {
                runOnUiThread(new Runnable() {  
                @Override                       
                public void run() { 
                    if(!isPost){
                        Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
                        isPost = true;
                        if( message.equals("Main Activity is going to pause")){
                            t.interrupt();
                        }

                    }
                }
               });
           if(Thread.currentThread().isInterrupted()){
               break;
           } 
         }
       }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    protected void onPause() {
        super.onPause();
        message = "Main Activity is going to pause";
        isPost = false;
    }

    @Override
    protected void onResume(){
       super.onResume();
       message = "Main Activity is going to resume";
       isPost = false;
       threadNameCounter++;
       t = new Thread(work,"My Name is " + String.valueOf(threadNameCounter));
       t.start();
    }

}

您还可以使用信号量或等待通知方法.

you can also use semaphore or wait-notify approach.

我将public String message = "";public boolean mustBePost = true;放入mSync对象,但是 不需要,因为只有main thread可以访问它们.

i put public String message = ""; and public boolean mustBePost = true; in to mSync object but it is not necessary because only main thread have an access to them.

如果有任何问题,请询问.

if you have any problem please ask.

这篇关于Android:暂停并恢复活动中的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆