1

簡単なアプリを作りました。

ユーザーが「Start ..」ボタンに触れると、ボタン ラベルに「ロード アニメーション」が表示されます。

PC でアプリケーション (デスクトップ アプリケーションなど) を作成しましたが、うまく機能します。

Android のアプリケーション コード:

package com.example.threaddot;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends Activity {

    SeekBar pointSpeed, numPoint;
    Button startButton, detailsButton;
    Thread count;
    boolean started = false;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // my vars
        startButton = (Button) findViewById(R.id.button_start);
        detailsButton = (Button) findViewById(R.id.button_details);
        numPoint = (SeekBar) findViewById(R.id.seekBar_numpoints);
        pointSpeed = (SeekBar) findViewById(R.id.PointSpeedSeekBar);

        count = new Thread(new Runnable() {

            @Override
            public void run() {
                setDots();
            }
        });

        startButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                count.start();
            }
        });

        detailsButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showAlert("Info",
                        String.format("Current: %s, %d points, and shown per %d m/s.", !started ? "working" : "suspend", 
                                numPoint.getProgress(), pointSpeed.getProgress()));             
            }
        });
    }

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

    public void setDots() {
        int counter = 0, numPoints = numPoint.getProgress();
        while(true) {
            if(counter++ < 10) {
                startButton.setText(startButton.getText() + ".  ");
            }

            else {
                counter = 0;
            }

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }           
    }

    void showAlert(String title, String msg) {
        AlertDialog alertDialog;
        alertDialog = new AlertDialog.Builder(this).create();
        alertDialog.setTitle(title);
        alertDialog.setMessage(msg);
        alertDialog.show();
    }
}

「開始..」ボタンを押すと、クラッシュします。

言い換えると、

startButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            count.start();
        }
    });

アプリケーションのクラッシュ。なぜ?

ログキャット:

01-18 20:07:43.453: W/dalvikvm(29186): threadid=10: thread exiting with uncaught exception (group=0x40018578)
01-18 20:07:43.500: E/AndroidRuntime(29186): FATAL EXCEPTION: Thread-11
01-18 20:07:43.500: E/AndroidRuntime(29186): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.view.ViewRoot.checkThread(ViewRoot.java:3055)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:649)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:675)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.view.View.invalidate(View.java:5279)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.widget.TextView.checkForRelayout(TextView.java:5782)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.widget.TextView.setText(TextView.java:2824)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.widget.TextView.setText(TextView.java:2685)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at android.widget.TextView.setText(TextView.java:2654)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at com.example.threaddot.MainActivity.setDots(MainActivity.java:66)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at com.example.threaddot.MainActivity$1.run(MainActivity.java:32)
01-18 20:07:43.500: E/AndroidRuntime(29186):    at java.lang.Thread.run(Thread.java:1019)
01-18 20:10:49.632: W/ActivityThread(29426): Application com.example.threaddot is waiting for the debugger on port 8100...
01-18 20:10:49.648: I/System.out(29426): Sending WAIT chunk
01-18 20:10:49.859: I/System.out(29426): Debugger has connected
01-18 20:10:49.859: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:50.054: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:50.257: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:50.460: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:50.664: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:50.867: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:51.062: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:51.265: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:51.468: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:51.671: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:51.875: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:52.085: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:52.281: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:52.500: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:52.695: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:52.898: I/System.out(29426): waiting for debugger to settle...
01-18 20:10:53.101: I/System.out(29426): debugger has settled (1476)
01-18 20:12:48.117: W/dalvikvm(29426): threadid=10: thread exiting with uncaught exception (group=0x40018578)
01-18 20:12:48.195: E/AndroidRuntime(29426): FATAL EXCEPTION: Thread-10
01-18 20:12:48.195: E/AndroidRuntime(29426): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.view.ViewRoot.checkThread(ViewRoot.java:3055)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:649)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:675)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.view.View.invalidate(View.java:5279)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.widget.TextView.checkForRelayout(TextView.java:5782)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.widget.TextView.setText(TextView.java:2824)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.widget.TextView.setText(TextView.java:2685)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at android.widget.TextView.setText(TextView.java:2654)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at com.example.threaddot.MainActivity.setDots(MainActivity.java:66)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at com.example.threaddot.MainActivity$1.run(MainActivity.java:32)
01-18 20:12:48.195: E/AndroidRuntime(29426):    at java.lang.Thread.run(Thread.java:1019)
01-18 20:14:52.031: D/AndroidRuntime(29761): Shutting down VM
01-18 20:14:52.031: W/dalvikvm(29761): threadid=1: thread exiting with uncaught exception (group=0x40018578)
01-18 20:14:52.062: E/AndroidRuntime(29761): FATAL EXCEPTION: main
01-18 20:14:52.062: E/AndroidRuntime(29761): java.lang.IllegalThreadStateException: Thread already started.
01-18 20:14:52.062: E/AndroidRuntime(29761):    at java.lang.Thread.start(Thread.java:1227)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at com.example.threaddot.MainActivity$2.onClick(MainActivity.java:40)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.view.View.performClick(View.java:2485)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.view.View$PerformClick.run(View.java:9080)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.os.Handler.handleCallback(Handler.java:587)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.os.Looper.loop(Looper.java:130)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at android.app.ActivityThread.main(ActivityThread.java:3687)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at java.lang.reflect.Method.invokeNative(Native Method)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at java.lang.reflect.Method.invoke(Method.java:507)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
01-18 20:14:52.062: E/AndroidRuntime(29761):    at dalvik.system.NativeStart.main(Native Method)
01-18 20:15:35.492: W/ActivityThread(29953): Application com.example.threaddot is waiting for the debugger on port 8100...
01-18 20:15:35.734: I/System.out(29953): Sending WAIT chunk
01-18 20:15:35.937: I/System.out(29953): Debugger has connected
01-18 20:15:35.937: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:36.140: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:36.343: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:36.546: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:36.742: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:36.945: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:37.148: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:37.359: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:37.554: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:37.757: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:37.960: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:38.164: I/System.out(29953): waiting for debugger to settle...
01-18 20:15:38.367: I/System.out(29953): debugger has settled (1495)
01-18 20:16:13.609: W/dalvikvm(29953): threadid=9: thread exiting with uncaught exception (group=0x40018578)
01-18 20:16:13.679: E/AndroidRuntime(29953): FATAL EXCEPTION: Thread-10
01-18 20:16:13.679: E/AndroidRuntime(29953): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.view.ViewRoot.checkThread(ViewRoot.java:3055)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:649)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:675)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.view.View.invalidate(View.java:5279)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.widget.TextView.checkForRelayout(TextView.java:5782)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.widget.TextView.setText(TextView.java:2824)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.widget.TextView.setText(TextView.java:2685)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at android.widget.TextView.setText(TextView.java:2654)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at com.example.threaddot.MainActivity.setDots(MainActivity.java:66)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at com.example.threaddot.MainActivity$1.run(MainActivity.java:32)
01-18 20:16:13.679: E/AndroidRuntime(29953):    at java.lang.Thread.run(Thread.java:1019)
01-18 20:21:29.492: D/AndroidRuntime(30489): Shutting down VM
01-18 20:21:29.492: W/dalvikvm(30489): threadid=1: thread exiting with uncaught exception (group=0x40018578)
01-18 20:21:29.632: E/AndroidRuntime(30489): FATAL EXCEPTION: main
01-18 20:21:29.632: E/AndroidRuntime(30489): java.lang.IllegalThreadStateException: Thread already started.
01-18 20:21:29.632: E/AndroidRuntime(30489):    at java.lang.Thread.start(Thread.java:1227)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at com.example.threaddot.MainActivity$2.onClick(MainActivity.java:40)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.view.View.performClick(View.java:2485)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.view.View$PerformClick.run(View.java:9080)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.os.Handler.handleCallback(Handler.java:587)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.os.Looper.loop(Looper.java:130)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at android.app.ActivityThread.main(ActivityThread.java:3687)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at java.lang.reflect.Method.invokeNative(Native Method)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at java.lang.reflect.Method.invoke(Method.java:507)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
01-18 20:21:29.632: E/AndroidRuntime(30489):    at dalvik.system.NativeStart.main(Native Method)
4

2 に答える 2

2

ログのように:

CalledFromWrongThreadException: ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。

Thread から Ui 要素にアクセスするように更新するには、次のようにrunOnUiThread()を実行する必要があることを意味します。

   MainActivity.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            // update textview here

        }
    });

setDots() メソッドを次のように変更します。

public void setDots() {
        int counter = 0, numPoints =0;
                MainActivity.this.runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                    numPoints = numPoint.getProgress();
                 }
               });
          while(true) {
            if(counter++ < 10) {
                MainActivity.this.runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                     startButton.setText(startButton.getText() + ".  ");
                 }
               });
            }

            else {
                counter = 0;
            }

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }           
    }
于 2013-01-18T18:25:00.967 に答える
0

「メイン」スレッド以外のスレッドでは、UI を扱うものを変更することはできません。定期的に情報を報告し、完了時に更新する機能を持つ AsyncTask の使用を検討する必要があります。「手っ取り早い」方法は、ハンドラーを作成し (UI スレッドで作成する必要があるため、アクティビティのインスタンス変数として初期化するか、oncreate、onXXX などで初期化する必要があります)、必要なときに UI スレッドに投稿することです。更新します。

これは、UI スレッドで作成する必要があります。

Handler handler = new Handler();

このハンドラーは、バックグラウンド スレッドに渡して、次のように更新を投稿できます。

handler.post(new Runnable()
{
    public void run() {
    //UI UPDATES HERE.
    }
});

あなたは本当にアンドロイドのドキュメントを読むべきです.それは完全であり、これらすべてを非常に詳細にカバーしています.

于 2013-01-18T18:34:10.230 に答える