проблема с запуском потока в Android - PullRequest
0 голосов
/ 15 июля 2011

У меня есть активность в 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)

Может кто-нибудь сказать, что я делаю не так?

Ответы [ 2 ]

1 голос
/ 03 мая 2012

Причина, по которой вы получаете это исключение, заключается в том, что запрещается останавливать и перезапускать один экземпляр объекта Thread.Вы вызываете start / stop в onResume / onPause соответственно, но вы никогда не перераспределяете объект потока (из 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 - даже при выходе из потока.

0 голосов
/ 15 июля 2011

поместите sleep (100) в блок try catch.

...