在Android中启动线程的问题

时间:2011-07-15 11:03:14

标签: android multithreading onresume

我在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传递给下一个活动:

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 个答案:

答案 0 :(得分: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。

答案 1 :(得分:-3)

将sleep(100)置于try catch块中。