所以我正在编写一个Android应用程序,当用户按下按钮时它会倒计时。一个线程运行倒计时。我的问题是,当我暂停应用程序时,我希望线程停止计数,然后在应用程序恢复后恢复。我的通知无法正常工作。谢谢!
public class MainActivity extends Activity {
private TextView mText;
private EditText mUserInput;
private CounterThread mCounterThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView)findViewById(R.id.text);
mUserInput = (EditText)findViewById(R.id.userInput);
mCounterThread = new CounterThread();
}
@Override
public synchronized void onPause(){
super.onPause();
mCounterThread.running = false;
}
@Override
public synchronized void onResume(){
super.onResume();
mCounterThread.running = true;
notify();//seems like this does nothing!
}
public void startCounterThread(){
mCounterThread.start();
}
public void button_handler(View v){
startCounterThread();
}
public void updateSeconds(final long seconds){
Runnable UIdoWork = new Runnable(){
public void run(){
String time = String.valueOf(seconds);
mText.setText("Your file will open in " + time + " seconds");
}
};
runOnUiThread(UIdoWork);
}
private class CounterThread extends Thread{
int count = 10;
boolean running = true;
@Override
public synchronized void run(){
while(count != 0){
while(!running){
try{
wait();//wait() will wait forever
//I don't want to put a time since
//I have no clue when the user will resume again
}catch(InterruptedException e){
e.printStackTrace();
}
}
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
updateSeconds(count--);
}
}
}
答案 0 :(得分:0)
因为wait()和notify()在用作锁的对象上工作,所以无法正常工作。当您在run()方法中运行wait()时,您正在使用CounterThread的实例作为锁,但是当您在onResume()方法中运行notify()时,您正在使用MainActivity的实例。 CounterThread永远不会收到通知。您的替代方案是(在您的onResume()方法中):
...
synchronized(mCounterThread) {
mCounterThread.notify();
}
...
答案 1 :(得分:0)
略有修改的代码:
public class MainActivity extends Activity {
private TextView mText;
private EditText mUserInput;
private CounterThread mCounterThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_2);
mText = (TextView) findViewById(R.id.text);
mUserInput = (EditText) findViewById(R.id.userInput);
mCounterThread = new CounterThread();
mCounterThread.start();
}
@Override
public synchronized void onPause() {
super.onPause();
mCounterThread.onPause();
}
@Override
public synchronized void onResume() {
super.onResume();
mCounterThread.onResume();
}
public void startCounterThread() {
mCounterThread.start();
}
public void button_handler(View v) {
startCounterThread();
}
public void updateSeconds(final long seconds) {
Runnable UIdoWork = new Runnable() {
public void run() {
String time = String.valueOf(seconds);
mText.setText("Your file will open in " + time + " seconds");
}
};
runOnUiThread(UIdoWork);
}
private class CounterThread extends Thread {
private int count = 10;
private final Object lock = new Object();
private volatile boolean isRunning = true;
public void onResume() {
if(!isRunning){
isRunning = true;
synchronized (lock){
lock.notify();
}
}
}
public void onPause() {
isRunning = false;
}
@Override
public void run() {
while (count != 0) {
synchronized (lock) {
if (!isRunning) try {
lock.wait();
} catch (InterruptedException e) {
//
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//
}
updateSeconds(count--);
}
}
}
}
running
必须标记为volatile
。它基本上意味着几个线程可以改变它,所有线程都会看到它。Thread
或Runnable
中公开。将活动用作监视器是非常糟糕的主意。在任何地方传递活动的参考是非常糟糕的主意。 Thread
和Activity
。使用一个内部线程。