【问题标题】:Android - Splash Screen without making another thread for main UIAndroid - 启动画面,无需为主 UI 创建另一个线程
【发布时间】:2013-04-04 17:58:42
【问题描述】:

这是我的第一个问题,我还是一个 Android 菜鸟(希望如此),所以如果我提出愚蠢的问题,请尽量原谅我。

我正在开发一个 Android 应用程序,我必须制作一个启动画面。我用这个答案做了一个:How do I make a splash screen?。它工作得很好,但是......这个解决方案为应用程序的其余部分创建了另一个大线程,我试图避免这种情况 - 我认为它会减慢整个应用程序(另一个应用程序线程)。我说的对吗?

我试图反转整个过程 - 我正在调用 MainMenu 活动,然后创建另一个线程只是为了启动:

public class MainMenu extends Activity implements OnItemClickListener { 

private GridView gridView;
private AlertDialog.Builder dialog;
private Intent intent;
private ApplicationPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    prefs = new ApplicationPreferences(this);
    setTheme(prefs.GetApplitacionTheme());
    SQLDatabase.onCreate();

    if (prefs.SplashScreenEnabled()) {
        new Runnable() {

            @Override
            public void run() {
                startActivity(new Intent(MainMenu.this, SplashScreen.class));                   
            }
        }.run();
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_menu);
    gridView = (GridView)findViewById(R.id.gridView);
    gridView.setAdapter(new AdapterMainMenu(this));
    gridView.setOnItemClickListener(this);
}

然后在我的 SplashScreen 活动中:

public class SplashScreen extends Activity {

private Locale locale;
private Configuration config;
private ApplicationPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash_screen);
}

@Override
protected void onResume() {
    try {
        Thread.sleep(2500);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finish();               
}

在 onCreate() Android 调用 onResume() 之后,我决定在这里暂停线程并在完成活动之后。

当应用程序回到主线程时它崩溃了,我不知道为什么。我做错了什么?

提前致谢! 安吉斯

【问题讨论】:

  • 发布您的 LogCat 错误。为什么 startActivity() 在 Runnable 中?您应该使用 Runnable 在 2.5 秒后关闭 SplashScreen,而不是使用 sleep()
  • 您的类命名约定(MainMenu 是活动而不是名称所示的菜单)会给您在更大的项目中带来麻烦...
  • 谢谢!我会更改它以避免出现问题。

标签: android multithreading screen splash-screen


【解决方案1】:

您不想在 onResume() 中调用 Thread.sleep(),因为这会阻塞 UI 线程。您首先使用Handler.postDelayed() 尝试的解决方案绝对是首选方式。为什么你认为它会创建一个“大”线程? Runnable.run() 实际上是使用该解决方案在主 UI 线程中调用的。

【讨论】:

  • 整个应用程序正在另一个用 Handler.postDelayed() 制作的线程中工作,因为我认为直到我结束 MainMenu 活动的那一刻(应用程序返回到调用 MainMenu 的 SplashScreen),然后以完成结束()。我认为它会减慢整个应用程序的速度。不是吗?
  • 如果你这样使用Handler,它总是会在UI Thread中执行Runnable,所以不会创建其他线程。顺便说一句:在 Android 中,所有的 Activity 生命周期方法,如 onCreate()、onResume() 等,也总是在 UI 线程中执行。
【解决方案2】:

您可以使用如下的计时器和处理程序

public class SplashScreen extends Activity{

Timer splashTimer;
SplashTimerHandler splashTimerHandler;

private boolean applicationPaused=false;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.main);

    this.setSplash();


}

private void setSplash() 
{
    this.splashTimerHandler=new SplashTimerHandler();
    this.splashTimer=new Timer();

    this.splashTimer.schedule(this.splashTimerHandler, 0, 1000);

}

@Override
public void onPause()
{
    super.onPause();
    this.applicationPaused=true;
    this.closeSplashTimer();
}

@Override
public void onResume()
{
    super.onResume();

    if(this.applicationPaused)
    {
        this.applicationPaused=false;
        this.closeSplashTimer();
        this.setSplash();
    }
}

public class SplashTimerHandler extends TimerTask{

    int splashTimerCounter=0;
    @Override
    public void run()
    {
        splashTimerCounter++;
        if(splashTimerCounter>2)
        {
            runOnUiThread(splashTimeOver);
        }       
    }

    private Runnable splashTimeOver=new Runnable() {

        @Override
        public void run()
        {
            closeSplashTimer();
            startHomeScreen();
        }
    };      
}

protected void closeSplashTimer() 
{
    if(this.splashTimer!=null)
    {
        this.splashTimer.cancel();
        this.splashTimer=null;
    }

}

private void startHomeScreen() 
{
    this.closeSplashScreen();
    startActivity(new Intent("com.example.MainActivity"));

}

private void closeSplashScreen()
{
    this.closeSplashTimer();
    this.finish();

}

@Override
public boolean onKeyDown(int keycode, KeyEvent event)
{
    if(keycode==KeyEvent.KEYCODE_BACK)
    {
        this.closeSplashScreen();
    }
    return true;
}

}

【讨论】:

    猜你喜欢
    • 2014-01-15
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    相关资源
    最近更新 更多