-1

私はアンドロイドが初めてで、タスクについて学んでいます。この例は、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」と表示され、バイブレーターが振動します。オーディオ サンプリングがスレッド内にあるオーディオ レコーダーを作成するという最終的な目標を達成するために、コードを少し再編成したかったのです。runnable と thread の宣言をクラスの先頭に移動してコードを再配置し、他のメソッドからそれらを参照できるようにしました。

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();
    }
}

アプリケーションを再度実行すると、最初にボタンを押したときに機能し、テキストが更新されてバイブレーターが振動しますが、2 回目にボタンを押すとプログラムがクラッシュします。スレッドが破棄されていることと関係があるのではないかと思いますが、クラスが破棄されるまでクラスの最初の宣言は破棄されないと思いました。それは別のものかもしれません。

ボタンを2回押したときにクラッシュする理由はありますか?

編集 - 要求に応じて、ここに 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