-1

私はJavaを初めて使用し、プラグインでEclipseを使用してAndroid用の簡単なアプリを作成しようとしています。コードは次のとおりです。

package com.example.pushthebutton;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {
    int counter = 30;
    TextView label;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int delay = 0; 
        int period = 1000;
        Timer timer = new Timer();
        label = (TextView) findViewById(R.id.textView1);
        timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    label.setText(String.valueOf("Time left: "));
                    counter--;
                }
            }, delay, period);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

エミュレータで実行すると、「残念ながら、アプリ名が停止しました」と表示されます。Logcat:

03-26 15:05:47.499: E/AndroidRuntime(1269): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:318)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.checkForRelayout(TextView.java:6452)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3696)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3554)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3529)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at com.example.pushthebutton.MainActivity$1.run(MainActivity.java:24)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at java.util.Timer$TimerImpl.run(Timer.java:284)
03-26 15:05:47.659: E/StrictMode(628): null

私はJavaを初めて使用します。Javaが何であるかわかりません。

4

3 に答える 3

4

UIスレッドとは異なるスレッドからすべてのビューを更新することはできません。

次のようにコードを変更します。

timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {

                runOnUiThread(new Runnable()
                    public void run() {
                        label.setText(String.valueOf("Time left: "));
                        counter--;
                        }
                  ));

            }
        }, delay, period);
}

setTextこのようにして、Androidに通話を実行するように依頼します。UI Thread

于 2013-03-26T15:17:21.163 に答える
2

これを試して:

 timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                runOnUiThread(new Runnable() {
                @Override
        public void run() {
        label.setText(String.valueOf("Time left: "));
                    counter--;
        }
            }
          }
        }, delay, period);

UIスレッドを非UIスレッド、つまりタイマーから変更しています。

于 2013-03-26T15:20:08.343 に答える
1

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

あなたはこのようにすることはできません。

label.setText(String.valueOf("Time left: "));

このようにしてください。

runOnUiThread(new Runnable() {
   public void run() {
      //Update UI Here
   }
});

またはこれを行うためのハンドラー。

void startHeavyDutyStuff() {

  // Here is the heavy-duty thread
  Thread t = new Thread() {

      public void run() {
          while (true) {

              mResults = doSomethingExpensive();

              //Send update to the main thread
              messageHandler.sendMessage(Message.obtain(messageHandler, mResults)); 
          }

      }
  };
  t.start();
}

// Instantiating the Handler associated with the main thread.
private Handler messageHandler = new Handler() {

      @Override
      public void handleMessage(Message msg) {  
          switch(msg.what) {
              //handle update
              //.....
          }
      }

  };
}
于 2013-03-26T15:17:29.490 に答える