0

背景として画像を表示する Android のアクティビティがあります。背景をクリックするとintent、別のアクティビティに移動するために使用されます。コードは次のようになります。

public class Precisari extends Activity{

    protected boolean _active = true;
    protected int _splashTime = 10000;
    public SplashThread  splashThread;


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

     splashThread=new SplashThread();

    }


    public class SplashThread extends Thread
    {
        public SplashThread()
        {

        }


        public void run() {

            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(getBaseContext(), com.SplashScreen.ConnectWithFb.class);
                startActivity(i);
                stop();

            }
        }

    }



    public boolean onTouchEvent(MotionEvent event){
        if(event.getAction()==MotionEvent.ACTION_DOWN){

            _active=false;
            }
        return true;
    }


    public void onResume(){
        super.onResume();
        _active=true;
        splashThread.start();
    }

    public void onPause()
    {
        super.onPause();
        splashThread.stop();

    }


}

で開始したスレッドを使用していますonResume()...このスレッドは、ブール_active変数が false に設定されるまでループします。エミュレーターの画面をクリックすると、変数が false に設定されます。

public boolean onTouchEvent(MotionEvent event){
            if(event.getAction()==MotionEvent.ACTION_DOWN){

                _active=false;
                }
            return true;
        }

次に、インテントを使用して次のアクティビティに渡します。

Intent i = new Intent(getBaseContext(), com.SplashScreen.ConnectWithFb.class);

スレッドは で開始されonResume()、 で停止しonPause()ます。アイデアは、このアクティビティに戻ったときに同じアイデアを機能させたいということです....画面をクリックすると次のアクティビティに渡されます!

私のlogcatは次のようになります。

 Uncaught handler: thread main exiting due to uncaught exception
 java.lang.RuntimeException: Unable to resume activity {com.SplashScreen/com.SplashScreen.Precisari}: java.lang.IllegalThreadStateException: Thread already started.
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2950)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4363)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.IllegalThreadStateException: Thread already started.               at java.lang.Thread.start(Thread.java:1322)
    at com.SplashScreen.Precisari.onResume(Precisari.java:101)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149)
    at android.app.Activity.performResume(Activity.java:3763)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2937)

誰かが私が間違っていることを教えてください??

4

2 に答える 2

1

その例外が発生する理由は、単一の Thread オブジェクト インスタンスを停止して再起動することが違法であるためです。onResume/onPause でそれぞれ start/stop を呼び出していますが、(onCreate から) スレッド オブジェクトを再割り当てすることはありません。

スレッドを停止して再開するには、Thread オブジェクトを再割り当てする必要があります。

この点に関して、Android のソースはかなり明確です。

// Thread.java, line ~178
/**
 * Reflects whether this Thread has already been started. A Thread
 * can only be started once (no recycling). Also, we need it to deduce
 * the proper Thread status.
 */
boolean hasBeenStarted = false;

// Thread.java, line ~1043
public synchronized void start()
{
    if (hasBeenStarted) {
        throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
    }

    hasBeenStarted = true;  // <--- Look here!

    VMThread.create(this, stackSize);
}

スレッドが終了した場合でも、 hasBeenStartedが false にリセットされることはありません。

于 2012-05-02T22:08:38.817 に答える
-3

sleep(100)をtrycatchブロックに入れます。

于 2011-07-15T11:14:36.353 に答える