7

次のコードは、アプリのスプラッシュ画面用です。アクティビティが読み込まれると、画像がデフォルトとして表示され、数秒後に同じアクティビティで別の画像に変更されます。最初のような別の色の画像があります。数秒後にその画像の画面を変更したかったのです。

私は自分のコードでこのようにそれを行いました。

package com.ruchira.busguru;

import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class SplashScreen extends Activity {

    ImageView imgBus;
    MediaPlayer introSound, bellSound;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);
        imgBus = (ImageView) findViewById(R.id.imgBus);
        imgBus.setImageResource(R.drawable.blackbus);
        introSound = MediaPlayer.create(SplashScreen.this, R.raw.enginestart);
        introSound.start();

                Thread timer = new Thread(){
            public void run(){
                try{
                    sleep(3000);
                } catch (InterruptedException e) {              
                    e.printStackTrace();
                }finally{
                   imgBus.setImageResource(R.drawable.bluekbus);    
                }
            }
        };
        timer.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.splash_screen, menu);
        return true;
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        introSound.stop();
        finish();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        introSound.stop();
        finish();
    }
}

しかし、問題は、プログラムがスレッドで実行されて停止することです...

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

どうすればこの目標を達成できますか?誰かが私がこの問題を解決するのを手伝ってくれませんか。私はAndroid開発に不慣れです。

ありがとう。

4

3 に答える 3

17

ImageViewのハンドラーとランナブルを使用する必要があります。ハンドラーはAndroidに固有のスケジューラーであり、UIスレッドで実行できます。これを試して:

ImageView imgBus;
MediaPlayer introSound, bellSound;
Runnable swapImage = new Runnable() {
    @Override
    public void run() {
        imgBus.setImageResource(R.drawable.bluekbus);
    }
};

そして内部のonCreate()呼び出し:

imgBus = (ImageView) findViewById(R.id.imgBus);
imgBus.setImageResource(R.drawable.blackbus);
imgBus.postDelayed(swapImage, 3000);  // Add me!

(バックグラウンドで遅い要素をロードしている間)できるだけ早くアプリを起動することに集中する必要があるため、スプラッシュ画面が嫌われていることを理解してください。ただし、わずかな遅延が避けられない場合もあります。

于 2012-11-14T06:45:44.123 に答える
2

最後にこれを中に書いてください

runOnUiThread(new Runnable() {
        public void run() {
                     SplashScreen.class.img.setImageResource(R.drawable.bluekbus);

                }
            });

常にUIスレッド自体からUIを更新する必要があります...

于 2012-11-14T07:34:25.347 に答える
0

次のことを試してください、

ワーカースレッドからUIにアクセスして更新することはできません。UIThreadからUIにアクセスできるのは私たちだけです。バックグラウンドスレッドで更新する必要がある場合は、次のコードのようにハンドラーを使用してこれを行うことができます。

    this.imgBus = (ImageView) findViewById(R.id.splashImageView);
    imgBus.setImageResource(R.drawable.your_first_image);
    this.handler = new Handler();
    introSound = MediaPlayer.create(SplashTestForSO.this, R.raw.enginestart);
    introSound.start();

            Thread timer = new Thread(){
        public void run(){
            try{


               sleep(2000);
                YourActivity.this.handler.post(runnable);  
              sleep(1000);
            } catch (InterruptedException e) {              
                e.printStackTrace();
            }finally{

            }
        }
    };

    timer.start();




    this.runnable = new Runnable() {
        public void run() {
            //call the activity method that updates the UI
            YourActivity.this.imgBus.setImageResource(R.drawable.your_scond_image_view);

        }
    };
于 2012-11-14T07:34:55.643 に答える