0

我正在编写一个简单的 android 应用程序来演示 wait() 和 notify() 方法。该应用程序包含 1 个按钮和 1 个 textView,textView 将显示一个计时器,而按钮将显示一个包含 2 个按钮的对话框。现在我想做的是每当我按下对话框按钮时,时间暂停,每当我通过按下对话框中的恢复按钮恢复时,时间继续等等。

这是我的代码:

public class MainActivity extends Activity implements OnClickListener{

Timer t;
int count = 0;

Button b;
TextView tv;

Thread thread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    b = (Button) findViewById(R.id.button1);
    tv = (TextView) findViewById(R.id.textView1);

    t = new Timer();
    t.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                public void run() {
                tv.setText(String.valueOf(count));
                count++;
                }
            });
        }
    }, 1000, 1000);

    b.setOnClickListener(this);


}


@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

    synchronized (MainActivity.this)
    {
        try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    final Dialog d = new Dialog(this);
    d.setTitle("Pause Menu");
    d.setContentView(R.layout.pausemenu);
    Button b1 = (Button) d.findViewById(R.id.Resume);
    Button b2 = (Button) d.findViewById(R.id.Main);

    b1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            d.cancel();
            thread = new Thread()
            {
                public void run()
                {
                    synchronized (MainActivity.this) {
                        try {
                            wait(1000);

                        }catch (Exception e) {
                            // TODO: handle exception
                        }

                        notify();
                    }
                }
            };
        }
    });

    b2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            d.cancel();
        }
    });
    d.show();

}
}

这是logcat:

06-09 08:07:55.066: E/AndroidRuntime(635): FATAL EXCEPTION: main
06-09 08:14:43.946: E/AndroidRuntime(664): FATAL EXCEPTION: main
06-09 08:14:43.946: E/AndroidRuntime(664): java.lang.NullPointerException
06-09 08:14:43.946: E/AndroidRuntime(664):  
at com.example.timerwithnotify.MainActivity.onClick(MainActivity.java:58)
06-09 08:14:43.946: E/AndroidRuntime(664):       
at  android.view.View.performClick(View.java:2408)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at android.view.View$PerformClick.run(View.java:8816)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at android.os.Handler.handleCallback(Handler.java:587)
 06-09 08:14:43.946: E/AndroidRuntime(664):     
at android.os.Handler.dispatchMessage(Handler.java:92)
06-09 08:14:43.946: E/AndroidRuntime(664):  at android.os.Looper.loop(Looper.java:123)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at android.app.ActivityThread.main(ActivityThread.java:4627)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at java.lang.reflect.Method.invokeNative(Native Method)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at java.lang.reflect.Method.invoke(Method.java:521)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-09 08:14:43.946: E/AndroidRuntime(664):  
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)

请用代码告诉我如何解决这个问题,我还是个菜鸟:D。感谢您的时间和考虑。

4

2 回答 2

1

不确定您要做什么。您可以参考以下内容。

如果您实现Thread or HandlerThread,请确保您的 UI 线程在等待工作线程完成时不会阻塞——不要调用Thread.wait()Thread.sleep()

检查这个 developer.android.com/training/articles/perf-anr.html

你不应该阻塞你的主 ui 线程。您可以使用“处理程序”代替计时器

您可以在单击按钮时启动和停止计时器。您可以使用计数值重新安排计时器。当活动被销毁和重新创建时,您需要注意方向变化。我们将重新初始化 count 的值。

MainActivity.java

public class MainActivity extends Activity implements OnClickListener{

Timer t;
int count = 0;
boolean isDone = true;
Button b;
TextView tv;

Thread thread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    b = (Button) findViewById(R.id.button1);
    tv = (TextView) findViewById(R.id.textView1);

    t = new Timer();
    t.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                public void run() {
                tv.setText(String.valueOf(count));
                if(isDone)
                count++;

                }
            });
        }
    }, 1000, 1000);

    b.setOnClickListener(this);


}


@Override
public void onClick(View v) {
    // TODO Auto-generated method stu

    final Dialog d = new Dialog(MainActivity.this);
    d.setTitle("Pause Menu");
    d.setContentView(R.layout.pausemenu);
    Button b1 = (Button) d.findViewById(R.id.button1);
    Button b2 = (Button) d.findViewById(R.id.button2);

    b1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            t.cancel();
            d.dismiss();

        }
    });

    b2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(isDone)
            {
                t.cancel();
                isDone=false;
            }
            t = new Timer();
             t.scheduleAtFixedRate(new TimerTask() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        runOnUiThread(new Runnable() {
                            public void run() {
                            tv.setText(String.valueOf(count));
                            count++;
                            }
                        });
                    }
                }, 1000, 1000);
             d.dismiss();
        }
    });
    d.show();

}
}

主要的.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
       android:textSize="20sp"
        android:text="TextView" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignRight="@+id/textView1"
        android:layout_marginBottom="21dp"
        android:text="Button" />

</RelativeLayout>

暂停菜单.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="118dp"
        android:layout_marginLeft="51dp"
        android:text="Stop" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button1"
        android:layout_alignBottom="@+id/button1"
        android:layout_marginLeft="32dp"
        android:layout_toRightOf="@+id/button1"
        android:text="Start" />

</RelativeLayout>

编辑:

使用处理程序

    Handler m_handler;
    Runnable m_handlerTask ; 
     m_handlerTask = new Runnable()
{
     @Override 
     public void run() {
         if(isDone)
         {
          tv.setText(""+count);
          count++;
          m_handler.postDelayed(m_handlerTask, 1000);
         }
        //  m_handler.removeCallbacks(m_handlerTask);
     }
};
m_handlerTask.run();    

您应该停止计时器并在不需要时取消处理程序。

t.cancel()如果您使用计时器并用于m_handler.removeCallbacks(m_handlerTask)停止处理程序 ,请调用

于 2013-06-09T06:38:03.230 回答
0

在您的代码中

   public void onClick(View v) {
        synchronized (MainActivity.this)
        {
            try {
                wait();

wait切勿使用该语句暂停 Android GUI 线程。暂停该线程将使所有 GUI 停止响应您的输入,Android 操作系统可能会在检测到这种情况后自动关闭程序。

此外,线程仅在您调用您从未执行过的 start 方法后才会启动。最后,您似乎在线程本身(内部类)上调用waitnotify,但其他地方没有代码调用通知,因此线程将永久停止。当然,如果您甚至从未启动它,这肯定不是问题。

我建议你阅读一些关于多线程的好教程。

于 2013-06-09T06:41:01.237 回答