Android:启动屏幕没有显示,为什么?

Android:启动屏幕没有显示,为什么?,android,splash-screen,Android,Splash Screen,我正在学习Android。从我迄今为止阅读的文档中,我不知道如何显示启动视图(在睡眠期间,屏幕保持空白)。看来我需要为主布局启动一个新的活动,但这似乎是浪费(飞溅应该永远消失,我想重用它的线程) 我相信你的闪屏永远不会显示出来,因为你从来没有给UI线程(你所在的)一个机会来绘制它,因为你只是在那里睡觉,什么也不做 我建议您不要使用Thread.sleep,而是使用一个或类似的工具来安排刷新和更改视图的内容;另一种方法是,像现在这样,在改变视图之前,先开始一个可以睡觉的地方 不要睡眠或以任何其他方

我正在学习Android。从我迄今为止阅读的文档中,我不知道如何显示启动视图(在睡眠期间,屏幕保持空白)。看来我需要为主布局启动一个新的活动,但这似乎是浪费(飞溅应该永远消失,我想重用它的线程)


我相信你的闪屏永远不会显示出来,因为你从来没有给UI线程(你所在的)一个机会来绘制它,因为你只是在那里睡觉,什么也不做

我建议您不要使用Thread.sleep,而是使用一个或类似的工具来安排刷新和更改视图的内容;另一种方法是,像现在这样,在改变视图之前,先开始一个可以睡觉的地方


不要睡眠或以任何其他方式阻止UI线程,这很糟糕。。。(导致ANR)

当您这样调用
sleep
时,您正在阻塞UI线程。相反,将对
setContentView
的第二个调用放在
Runnable
中,创建一个处理程序,并使用处理程序的
postDelayed
方法运行Runnable。大概是这样的:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash);
    Runnable endSplash = new Runnable() {
        @Override
        public void run() {
            setContentView (R.layout.main);
        }
    }
    new Handler().postDelayed(endSplash, 5000L);
}

我已经在我的应用程序中尝试了这段代码,它工作得很好。也许它会对你有所帮助

public class SplashScreen extends Activity {

    /**
     * The thread to process splash screen events
     */
    private Thread mSplashThread;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Splash screen view
        setContentView(R.layout.splash);



        final SplashScreen sPlashScreen = this;

        // The thread to wait for splash screen events
        mSplashThread = new Thread() {
            @Override
            public void run() {
                try {
                    synchronized (this) {
                        // Wait given period of time or exit on touch
                        wait(5000);
                    }
                } catch (InterruptedException ex) {
                }

                finish();

                // Run next activity
                Intent intent = new Intent();
                intent.setClass(sPlashScreen, MainActivity.class);
                startActivity(intent);
                stop();
            }
        };

        mSplashThread.start();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        return false;
    }

    /**
     * Processes splash screen touch events
     */
    @Override
    public boolean onTouchEvent(MotionEvent evt) {
        if (evt.getAction() == MotionEvent.ACTION_DOWN) {
            synchronized (mSplashThread) {
                mSplashThread.notifyAll();
            }
        }
        return true;
    }

}

这是基本启动屏幕的代码片段

public class Splash extends Activity {

//private ProgressDialog pd = null;
private final int SPLASH_DISPLAY_LENGTH = 3000; 

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.splashscreen);
    //this.pd = ProgressDialog.show(this, "Initializing..", "Initializing Infraline...", true, false);

    /* New Handler to start the InfralineTabWidget-Activity
     * and close this Splash-Screen after some seconds.*/

    new Handler().postDelayed(new Runnable(){
        @Override
        public void run() {
        /* Create an Intent that will start the InfralineTabWidget-Activity. */
            Intent mainIntent = new Intent(Splash.this,InfralineTabWidget.class);
            Splash.this.startActivity(mainIntent);
            Splash.this.finish();
        }
    }, SPLASH_DISPLAY_LENGTH);

}

}
在您的AndroidManifest.xml中

    <activity android:name=".Splash" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|keyboardHidden">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>


希望这对您有用:)

有关如何实现这一点的示例,请参见。显然,我认为调用函数和返回其完成的工作之间的关系是错误的。这严重地影响了我所讨论的机器型号。显然,线程所做的比我的代码还多。这些操作是什么以及何时执行?@kasterma-这在活动指南的和部分的活动生命周期下进行了描述。因此,在UI线程中,工作由其他代码完成,我的代码只是将一些变量“设置”为正确的值。我读过活动生命周期,但不理解导入。你是对的,UI线程是完成所有绘图、布局等的线程。。。它的一部分是调用您的活动来设置所有这些组件。如果您阻止它(睡眠或等待),那么您将冻结您的用户界面,并使您的应用程序无响应。请参阅@Matthieu回答中的我的评论,我希望UI线程中的睡眠会阻止任何进一步的交互。但我已经设定了布局;使用我的心智模型,我应该不能再阻止任何东西了。设置布局不会自动导致屏幕渲染。这是在
onCreate
返回后执行的框架内的代码。因为在更改内容视图之前您不会返回,所以启动屏幕从来没有机会。应用程序的整个UI在睡眠期间被暂停。启动一个新活动肯定比启动一个新线程要多。@kasterma-不一定。对于这种方法有很多话要说。例如,它将启动屏幕与主要活动分开。它的主要问题是启动屏幕(在我看来)的主要目的是进行耗时的初始化,这将阻止主视图立即显示。在单独的启动活动中进行初始化意味着必须将初始化的数据传输到主活动。(顺便说一句,在线程的run()方法中调用不推荐的stop()方法是错误的;我不知道人们为什么这么做。)
    <activity android:name=".Splash" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="orientation|keyboardHidden">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>