0

そこで、モバイル プログラミング コース用に作成している単純な Android ゲーム用に、単純な「スプラッシュ スクリーン」(イントロ スクリーンのようなもの) を作成し始めました。それ以来、私は問題に遭遇しました。スレッドを使用することになっていることはわかっていますが、実装が機能していないようです。私が目指している効果を実感していただけるはずです。

public class SplashScreen extends Activity {

//how long until we go to the next activity
protected int splashTime = 2000; 
private Thread splashThread;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash_screen);

    final TextView first = (TextView) findViewById(R.id.textView1);
    final TextView second = (TextView) findViewById(R.id.textView2);
    final TextView third = (TextView) findViewById(R.id.textView3);
    final TextView fourth = (TextView) findViewById(R.id.textView4);
    final TextView fifth = (TextView) findViewById(R.id.textView5);
    final TextView sixth = (TextView) findViewById(R.id.textView6);
    final ImageView main_character = (ImageView) findViewById(R.id.imageView1);

    // thread for displaying the SplashScreen
    splashThread = new Thread() {
        @Override
        public void run() {
            try {
                synchronized(this){

                    first.setText("The year is 2048...");

                    wait(splashTime);

                    first.setText("");
                    second.setText("...the Earth's resources have long been depleted");

                    wait(splashTime);

                    second.setText("");
                    third.setText("Attempts have been made to save our home...");

                    wait(splashTime);

                    third.setText("");
                    fourth.setText("...but all has gone awry, trash now rains from the skies");

                    wait(splashTime);

                    fourth.setText("");
                    fifth.setText("Now, only one man can save us, and his name is...");

                    wait(splashTime);

                    fifth.setText("");
                    sixth.setText("The Garbage Man!");
                    main_character.setImageResource(drawable.bobrgb888);

                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            finally {
                finish();

                //start a new activity
                Intent i = new Intent(getApplicationContext(), MainMenu.class);
                startActivity(i);
            }
        }
    };
    splashThread.start();

}

問題は、最初のテキストビューが最初のwait()呼び出しとともに呼び出されることですが、その後、強制終了します。

これが私のlogcatです:

07-02 19:35:16.241: W/dalvikvm(709): threadid=9: thread exiting with uncaught exception (group=0x40015560)
07-02 19:35:16.250: E/AndroidRuntime(709): FATAL EXCEPTION: Thread-10
07-02 19:35:16.250: E/AndroidRuntime(709):     android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a    view hierarchy can touch its views.
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.ViewRoot.requestLayout(ViewRoot.java:629)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.View.requestLayout(View.java:8267)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.View.requestLayout(View.java:8267)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.View.requestLayout(View.java:8267)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.View.requestLayout(View.java:8267)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:257)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.view.View.requestLayout(View.java:8267)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.widget.TextView.checkForRelayout(TextView.java:5521)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.widget.TextView.setText(TextView.java:2724)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.widget.TextView.setText(TextView.java:2592)
07-02 19:35:16.250: E/AndroidRuntime(709):  at android.widget.TextView.setText(TextView.java:2567)
07-02 19:35:16.250: E/AndroidRuntime(709):  at com.connor.black.SplashScreen$1.run(SplashScreen.java:41)
07-02 19:35:16.420: D/szipinf(709): Initializing inflate state
4

4 に答える 4

2

ここでスレッドを使用する場合は、startを呼び出してスレッドを開始する必要があります。これにより、run()メソッドが呼び出されます。

splashTread = new Thread() {
    @Override
    public void run() {
      ...
    }
};

splashThread.start();

これはバックグラウンドで実行されることに注意してください。つまり、UIスレッドではありません。

于 2012-07-02T23:28:27.823 に答える
1

これは、SplashScreen に使用したコードです。

final SplashScreen splash = this;

Thread splashThread = new Thread() {
        @Override
        public void run() {
            go = true;
            while (go) {
            try {
                int waited = 0;
                while(_active && (waited < _splashTime)) {
                    sleep(100);
                    if(_active) {
                        waited += 100;
                    }
                }
            } catch(InterruptedException e) {
                // do nothing
            } finally {
                finish();
                Intent i = new Intent();
                i.setClass(splash, MyActivity.class);
                startActivity(i);
                //stop();
                go = false;
            }
            }
        }
    };
    splashThread.start();

スプラッシュスクリーンの問題は、wait() の使い方が間違っていることです。探しているのは sleep() です。

また、ワーカー スレッドから UI スレッドにアクセスするには、runOnUiThread(Runnable action) またはハンドラーを使用する必要があります。

于 2012-07-02T23:33:16.903 に答える
0

SplashThread Thread内のコードを次のように置き換えます。

runOnUiThread(new Runnable() {
    public void run() {
        first.setText("The year is 2048...");
        //... The rest of code goes here too.
    }
});

そうすれば、UI スレッドはそのビューに完全に触れることができます。

于 2012-07-03T00:05:03.503 に答える
0

UIに触れるにはハンドラーを使用する必要があります(つまり、テキストビューのテキストを設定します)

スレッド宣言のすぐ上に、次のように記述します。

Handler handler = new Handler();

次に、する代わりにfirst.setText("bla bla bla");

行う

handler.post(new Runnable(){
  public void run(){
    first.setText("bla bla bla");
  }
});

別のスレッドは UI 要素に触れることができないため、これを行う必要があります。ハンドラーを使用すると、基本的に、渡したものを実行するように UI スレッドに指示されます。

于 2012-07-02T23:41:25.230 に答える