Search code examples
javaandroidandroid-activity

Why Fade in Activity Transition only works by using Handler but not Thread?


I am working on an app and I want to implement a auto transition effect on the SplashScreen.

I have tried Thread, but the transition is not showing.

However, if I used Handler instead, the transition works fine.

Why it only works on Handler? Can somebody please explain to me?

Handler version

public class SplashScreen extends AppCompatActivity { //Works

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {

            Intent i = new Intent(getApplicationContext(),MainActivity.class);
            startActivity(i);
            overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
            finish();
        }
    }, 5000);
}

Thread version

public class SplashScreen extends AppCompatActivity { //Not Working

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);
    Thread myThread = new Thread(){
        @Override
        public void run() {
            try {
                sleep(3000);
                Intent i = new Intent(getApplicationContext(),MainActivity.class);
                startActivity(i);
                overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
                finish();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    myThread.start();
}

The fade_in.xml and fade_out.xml were from https://stackoverflow.com/a/18475926/9386861


Solution

  • You can only perform UI operations on the main/UI thread.

    The Handler is on the UI thread by default in this case.. And when you're creating a new Thread, it's not the main/UI Thread.

    So (for example) if you wanted to run this operation from the Thread you created you can do the Following:

    new Thread() {
      @Override
      public void run() {
        super.run();
    
        Handler handler = new Handler(Looper.getMainLooper()); //Create a Handler to run on the main/UI Thread like this.
        handler.post(new Runnable() {
          @Override
          public void run() {
            // Your operation on the UI Thread
          }
        });
      }
    }.start();
    

    You can read about the Handler constructors and Loopers to understand the behaviour: https://developer.android.com/reference/android/os/Handler.html