0

所以我开始为我正在为移动编程课程制作的简单安卓游戏制作一个简单的“启动画面”(它更像是一个介绍屏幕)。从那以后我遇到了问题。我知道我应该使用线程,但我的实现似乎不起作用。你应该能够感受到我想要的效果。

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

}

问题是第一个 textview 与第一个 wait() 调用一起被调用,但随后我强制关闭。

这是我的日志:

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

您需要使用处理程序来触摸 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 回答
0

将您的代码替换为splashThread Thread 中的代码,例如:

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

这样 UI Thread 就可以完美地触及它的视图。

于 2012-07-03T00:05:03.503 回答