Thread stopping issue android

2019-07-16 07:51发布

问题:

I want to stop a running thread while click on the splash screen, if I don't click on screen, after the thread execution, it will launch another Activity. But getting UnSupportedException, how do I solve it?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    iImage = (ImageView) findViewById(R.id.iIcon);
    splashImage = (ImageView) findViewById(R.id.splash_image);

    iImage.setOnClickListener(this);
    splashImage.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    splashTimer = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            startActivity(new Intent(SplashActivity.this, LoginAuthenticationActivity.class));
            finish();
        }
    });
    splashTimer.start();
}

@Override
public void onClick(View view) {
    if(splashTimer.isAlive())
        splashTimer.stop();
    switch (view.getId()) {
        case R.id.iIcon:
            startActivity(new Intent(this, AboutUsActivity.class));
            break;
        case R.id.splash_image:
            startActivity(new Intent(this, LoginAuthenticationActivity.class));
            break;
        default:
            break;
    }
    finish();
}

Log:

01-27 03:27:01.189: W/dalvikvm(1080): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
01-27 03:27:01.209: E/AndroidRuntime(1080): FATAL EXCEPTION: main
01-27 03:27:01.209: E/AndroidRuntime(1080): java.lang.UnsupportedOperationException
01-27 03:27:01.209: E/AndroidRuntime(1080):     at java.lang.Thread.stop(Thread.java:1076)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at java.lang.Thread.stop(Thread.java:1063)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at com.app.wooqer.SplashActivity.onClick(SplashActivity.java:48)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.view.View.performClick(View.java:3511)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.view.View$PerformClick.run(View.java:14105)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.os.Handler.handleCallback(Handler.java:605)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.os.Looper.loop(Looper.java:137)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at android.app.ActivityThread.main(ActivityThread.java:4424)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at java.lang.reflect.Method.invokeNative(Native Method)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at java.lang.reflect.Method.invoke(Method.java:511)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-27 03:27:01.209: E/AndroidRuntime(1080):     at dalvik.system.NativeStart.main(Native Method)

回答1:

What you're doing is very wasteful (any splash screen is wasteful, but using Threads like this is more so), but to fix your issue:

use interrrupt(); intead of stop();

As the docs say for stop()

Throws UnsupportedOperationException.

And to fix the duplicate issue, move the startActivity() inside the try so it looks like this:

public void run() {
  try {
    Thread.sleep(5000);
    startActivity(new Intent(SplashActivity.this, LoginAuthenticationActivity.class));
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  finish();
}

That way when you call interrupt() all your Activity does is finish() and the duplicate startActivity() is not called.

To further explain:

Very first issue: stop() throws an exception by default, since it's an unsafe method which you're not supposed to use.

Then when you used interrupt(), you had startActivity() in the run method after the catch block. When you interrupted, startActivity() was called once in run() and once in onClick(). By moving startActivity() inside the try block to right after Thread.sleep(), when interrupt() interrupts the Thread, the rest of the try block isn't executed. This means that you now only have one startActivity() call instead of two. For more information, read up on exceptions.