我正在尝试按照以下规则创建一个包含横幅和取消按钮的Splash页面:
我的代码:
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()
我该如何实现该逻辑?
答案 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();
}
}
投票......如果你得到帮助..