Android可取消的启动画面

时间:2014-02-24 13:28:04

标签: android android-asynctask splash-screen

我正在尝试按照以下规则创建一个包含横幅和取消按钮的Splash页面:

  1. 如果没有按下任何内容,请在5秒后进入主要活动。
  2. 如果按下取消按钮,立即转到主要活动。
  3. 如果按了横幅,请转到其他活动。
  4. 我的代码:

    public class BannerSplashActivity extends Activity {
        private static final int TIMEOUT = 5000;
    
        private View mButtonCancel;
        private SplashHolderTask mSplashHolderTask;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.form_banner_splash);
    
            // Excecute task
            mSplashHolderTask = new SplashHolderTask();
            mSplashHolderTask.execute();
    
            // find references
            mButtonCancel = findViewById(R.id.buttonCancel);
            mButtonCancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mSplashHolderTask.cancel(true);
                    goToMainActivity();
                }
            });
        }
    
        private void goToMainActivity(){
            startActivity(new Intent(this, MainActivity.class));
            finish();
        }
    
    
        /**
         * This task holds the bannerSplash
         */
        private class SplashHolderTask extends AsyncTask<Void, Void, Void>{
    
            @Override
            protected Void doInBackground(Void... params) {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        goToMainActivity();
                    }
                }, TIMEOUT);
    
                return null;
            }
        }
    }
    

    当我运行我的代码时,我得到了:

    Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    

    我该如何实现该逻辑?

5 个答案:

答案 0 :(得分:3)

您无法在AsyncTask中创建线程。您可以简单地使用一个简单的延迟处理程序,如果单击横幅,取消按钮或用户离开应用程序,您将取消:

public class BannerSplashActivity extends Activity {
    private static final int TIMEOUT = 5000;

    private Handler cancelHandler;

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

      cancelHandler = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
             goToMainActivity();
        }
      };
      cancelHandler.sendEmptyMessageDelayed(0, TIMEOUT);

      // find references
      View mButtonCancel = findViewById(R.id.buttonCancel);
      View mBannerView = findViewById(R.id.bannerView);

      mButtonCancel.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              cancelHandler.removeMessages(0);
              goToMainActivity();
          }
      });

      mBannerView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              cancelHandler.removeMessages(0);
              //go to the activity you want
          }
      });
 }

  private void goToMainActivity(){
      startActivity(new Intent(this, MainActivity.class));
      finish();
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    if(cancelHandler != null){
      cancelHandler.removeMessages(0);
    }
  }
}    

答案 1 :(得分:2)

Exception,因为您在另一个帖子中创建了Handler .. 通过这样更改您的代码,您可以得到您想要的......

public class BannerSplashActivity extends Activity {
private static final int TIMEOUT = 5000;

private View mButtonCancel;

private Handler handler = new Handler();
private Runnable runnable;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.form_banner_splash);
    runnable = new Runnable() {

        @Override
        public void run() {
            goToMainActivity();
        }
    };
    handler.postDelayed(runnable, TIMEOUT);

    // find references
    mButtonCancel = findViewById(R.id.buttonCancel);
    mButtonCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            handler.removeCallbacks(runnable);
            goToMainActivity();
        }
    });
}

private void goToMainActivity() {
    startActivity(new Intent(this, MainActivity.class));
    finish();
}
}

我没有使用任何Threads或AsynchTasks。

答案 2 :(得分:2)

Handler和Runnable就足够了。

Handler mHandler;
Runnable mRunnable;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.form_banner_splash);

    mHandler = new Handler();
    mRunnable = new Runnable() {
        @Override
        public void run() {
            goToMainActivity();
        }
    };

    mHandler.postDelayed(mRunnable, TIMEOUT);

    mButtonCancel = findViewById(R.id.buttonCancel);
    mButtonCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            handler.removeCallBacks(mRunnable);
            goToMainActivity();
        }
    });

    private void goToMainActivity(){
        startActivity(new Intent(this, MainActivity.class));
        finish();
    }
}

答案 3 :(得分:2)

使用Thread.sleep(x)(计时器),在另一个thread中运行就足够了:

public class SplashScreen extends Activity {
    private static final int splash_duration = 5000;
    private boolean mPaused = false;
    private boolean mActive = true;
    private Thread splashTimer = null;

        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
            setContentView(R.layout.splash);

            Button cancel = (Button)findViewById(R.id.cancel);
            View bannerWidget = (Banner)findViewById(R.id.someBanner);



            cancel.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                //cancel button is pressed, go to main activity                     immediately.
                Intent intent = new Intent("com.foo.MainActivity");
                startActivity(intent);

                }
            });

            bannerWidget.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                //banner is pressed, go to other activity.
                Intent intent = new Intent("com.foo.OtherActivity");
                startActivity(intent);

                }
            });

            splashTimer = new Thread(new Runnable() {
                public void run() {
                    long current_time = 0;
                    try {

                        while (mActive && current_time < splash_duration) {
                            Thread.sleep(200);
                            if (!mPaused)
                                current_time += 200;
                        }
                        //nothing is pressed, go to main activity after 5 seconds.
                        Intent intent = new Intent("com.foo.MainActivity");
                        startActivity(intent);
                    } catch (Exception ex) {
                        Log.e("Splash", ex.toString());
                    } finally {
                        finish();
                    }
                }
            });
            splashTimer.setDaemon(true);
            splashTimer.start();
        }

        @Override
        protected void onPause() {
            super.onPause();
            mPaused = true;
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (splashTimer != null) {
                Thread dummy = splashTimer;
                splashTimer = null;
                dummy.interrupt();
            }

        }

        @Override
        protected void onResume() {
            super.onResume();
            mPaused = false;
        }

        @Override
        public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
            super.onKeyDown(keyCode, keyEvent);
            mActive = false;
            return true;
        }
}

答案 4 :(得分:0)

已经回答,但有人正在寻找onBackPressed()然后使用简单的完整活动......

public class ActivityLaunch extends Activity {

    private static int SPLASH_TIME_OUT = 3000;
    Handler mHandler;
    Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activitylaunch);

        mHandler = new Handler();
        runnable = new Runnable() {

            @Override
            public void run() {
                Intent i = new Intent(ActivityLaunch.this, ActivityHome.class);
                startActivity(i);
                finish();
            }
        };
        mHandler.postDelayed(runnable, SPLASH_TIME_OUT);
    }

    @Override
    public void onBackPressed() {
        mHandler.removeCallbacks(runnable);
        finish();
    }
}

投票......如果你得到帮助..