-1

我是android新手,正在学习任务。我在使用 runnable 的教程中找到了这个示例。

public class ThreadExample extends Activity {

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            TextView myTextView = (TextView)findViewById(R.id.myTextView);
            String ReturnedInt = Integer.toString(msg.what);
            myTextView.setText(ReturnedInt);

            Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            v.vibrate(1500);   // Vibrate for 1500 milliseconds
        }
    };

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


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.thread_example, menu);
        return true;
    }

    public void buttonClick(View view)
    {
        Runnable runnable = new Runnable() {
            public void run() {
                long endTime = System.currentTimeMillis() + 2*1000;
                while (System.currentTimeMillis() < endTime) {
                    synchronized (this) {
                        try {
                            wait(endTime - System.currentTimeMillis());
                        }
                        catch (Exception e) {
                        }   
                        }
                }
                handler.sendEmptyMessage(1234);    
            }
        };
        Thread mythread = new Thread(runnable);
        mythread.start();
    }
}

此代码有效。如果我按下屏幕上的按钮,文本框会显示“1234”并且振动器会振动。我想重新排列代码,以满足我编写录音机的最终目标,音频采样将在线程中。我通过将可运行和线程声明移动到类的顶部来重新排列代码,因此我可以从其他方法中引用它们

public class ThreadExample extends Activity {

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            TextView myTextView = (TextView)findViewById(R.id.myTextView);
            String ReturnedInt = Integer.toString(msg.what);
            myTextView.setText(ReturnedInt);

            Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            v.vibrate(1500);   // Vibrate for 1500 milliseconds
        }
    };

    Runnable runnable = new Runnable() {
        public void run() {
            long endTime = System.currentTimeMillis() + 2*1000;
            while (System.currentTimeMillis() < endTime) {
                synchronized (this) {
                    try {
                        wait(endTime - System.currentTimeMillis());
                    }
                    catch (Exception e) {
                    }   
                    }
            }
            handler.sendEmptyMessage(1234);    
        }
    };
    Thread mythread = new Thread(runnable);

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


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.thread_example, menu);
        return true;
    }

    public void buttonClick(View view)
    {
        mythread.start();
    }
}

如果再次运行应用程序,在我第一次按下按钮时可以正常工作,文本会更新并且振动器会振动,但第二次按下按钮时程序会崩溃。我认为这可能与线程被销毁有关,但我认为类开始时的声明在类被销毁之前不会被销毁。它可能是别的东西。

任何想法为什么它在我第二次按下按钮时崩溃?

编辑 - 根据要求,这里是 logcat 输出

08-11 09:49:37.489: W/dalvikvm(5014): threadid=1: thread exiting with uncaught exception (group=0x2aac8560)
08-11 09:49:37.509: E/AndroidRuntime(5014): FATAL EXCEPTION: main
08-11 09:49:37.509: E/AndroidRuntime(5014): java.lang.IllegalStateException: Could not execute method of the activity
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.view.View$1.onClick(View.java:2168)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.view.View.performClick(View.java:2552)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.view.View$PerformClick.run(View.java:9229)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.os.Handler.handleCallback(Handler.java:587)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.os.Looper.loop(Looper.java:123)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.app.ActivityThread.main(ActivityThread.java:3701)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at java.lang.reflect.Method.invokeNative(Native Method)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at java.lang.reflect.Method.invoke(Method.java:507)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at dalvik.system.NativeStart.main(Native Method)
08-11 09:49:37.509: E/AndroidRuntime(5014): Caused by: java.lang.reflect.InvocationTargetException
08-11 09:49:37.509: E/AndroidRuntime(5014):     at java.lang.reflect.Method.invokeNative(Native Method)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at java.lang.reflect.Method.invoke(Method.java:507)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at android.view.View$1.onClick(View.java:2163)
08-11 09:49:37.509: E/AndroidRuntime(5014):     ... 11 more
08-11 09:49:37.509: E/AndroidRuntime(5014): Caused by: java.lang.IllegalThreadStateException: Thread already started.
08-11 09:49:37.509: E/AndroidRuntime(5014):     at java.lang.Thread.start(Thread.java:1227)
08-11 09:49:37.509: E/AndroidRuntime(5014):     at com.example.threadexample.ThreadExample.buttonClick(ThreadExample.java:60)
08-11 09:49:37.509: E/AndroidRuntime(5014):     ... 14 more
4

1 回答 1

2

这是主要原因:

Caused by: java.lang.IllegalThreadStateException: Thread already started.
    at java.lang.Thread.start(Thread.java:1227)
    at com.example.threadexample.ThreadExample.buttonClick(ThreadExample.java:60)

您不能重复使用相同的Thread对象。在再次调用之前,您必须创建一个新Thread对象.start()

文档中:

多次启动一个线程是不合法的。特别是,线程一旦完成执行就可能不会重新启动。

于 2013-08-11T18:17:53.423 回答