Java Android 在加载时显示启动画面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31473557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:09:35  来源:igfitidea点击:

Android display Splash-Screen while loading

javaandroidsplash-screen

提问by HorstB

I have an Android App, which shows a "Splash Screen" for 3 seconds. After that, the MainActivity gets loaded.

我有一个 Android 应用程序,它显示 3 秒钟的“启动画面”。之后,加载 MainActivity。

Unfortunately the MainActivity takes additional ~4 seconds to load. On first startup even longer. However when the App is loaded, everything runs smooth.

不幸的是 MainActivity 需要额外约 4 秒才能加载。在第一次启动时甚至更长。然而,当应用程序加载时,一切运行顺利。

Now how can I achieve it, that the MainActivity gets loaded, during the display of the Splash Screen? It just should display an image until the whole thing loaded completely. I have read about Async-Task, but I'm not sure where to put it and how to use it properly. Can someone help me please?

现在我怎样才能实现它,在启动画面的显示期间加载 MainActivity?它只应该显示一个图像,直到整个内容完全加载。我已经阅读了 Async-Task,但我不确定将它放在哪里以及如何正确使用它。有人能帮助我吗?

SplashScreen.java

启动画面.java

public class SplashScreen extends Activity {
    private static int SPLASH_TIME_OUT = 3000;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_startup);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent i = new Intent(SplashScreen.this, MainActivity.class);
                startActivity(i);
                finish();
            }
        }, SPLASH_TIME_OUT);
    }
}

MainActivity.java

主活动.java

public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl {

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

        //Some heavy processing
        //starting services
        //starting Google Text to Speech
        //and so on...

    }

}

采纳答案by TmKVU

If there are no specific constraints about the time the splash screen should be shown, you could use the AsyncTaskin the following way:

如果没有关于应该显示初始屏幕的时间的特定限制,您可以AsyncTask按以下方式使用:

public class SplashScreen extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_startup);
        startHeavyProcessing();

    }

    private void startHeavyProcessing(){
       new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            //some heavy processing resulting in a Data String
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "whatever result you have";
        }

        @Override
        protected void onPostExecute(String result) {
            Intent i = new Intent(SplashScreen.this, MainActivity.class);
            i.putExtra("data", result);
            startActivity(i);
            finish();
        }

        @Override
        protected void onPreExecute() {}

        @Override
        protected void onProgressUpdate(Void... values) {}
    }
}

If the resulting data if of another nature than a String you could put a ParcelableObject as an extra to your activity. In onCreateyou can retrieve the data with:

如果结果数据的性质不同于字符串,您可以将一个Parcelable对象作为您的活动的额外内容。在onCreate你可以检索数据:

getIntent().getExtras.getString('data');

getIntent().getExtras.getString('data');

回答by Puneet Kumar

your splash screen code works fine but when you call next activity then in onCreate() use Asynctask for your heavy tasks...

您的初始屏幕代码工作正常,但是当您调用下一个活动时,然后在 onCreate() 中使用 Asynctask 执行繁重的任务...

回答by Theo Lassonder

How about, in the interest of simplicity, you combine your splash activity with your main activity? That way you get the best of both worlds, namely a splash screen while your data is preparing the first time, and a quick startup when it's been prepared previously. Making the user wait for nothing is not really good form...

为了简单起见,您将飞溅活动与主要活动结合起来如何?这样您就可以两全其美,即第一次准备数据时的启动画面,以及之前准备好的快速启动。让用户什么都不等待并不是一个很好的形式......

Something like:

就像是:

public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl {

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

        // Initially shows splash screen, the main UI is not visible
        setContentView(R.layout.activity_main);  

        // Start an async task to prepare the data. When it finishes, in
        // onPostExecute() get it to call back dataReady()
        new PrepareDataAsyncTask(this).execute();

    }

    public void dataReady() {
        // Hide splash screen
        // Show real UI
    }

}

回答by Bryan

You should not be creating a new thread on startup, instead you should create a view that does not have to wait for your resources to load, as detailed in this article: Splash Screens the Right Way.

您不应该在启动时创建新线程,而应该创建一个不必等待资源加载的视图,如本文所述:Splash Screens the Right Way

As stated in the article, you should create a layer-listdrawable instead of a layoutXML file:

如文章所述,您应该创建一个layer-listdrawable 而不是layoutXML 文件:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Fill the background with a solid color -->
    <item android:drawable="@color/gray"/>

    <!-- Place your bitmap in the center -->
    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

Then create a theme using the drawable file as a background. I use the backgroundattribute instead of the windowBackgroundattribute as suggested in the article, because backgroundtakes the status and navigation bars into account, centering the drawable better. I also set windowAnimationStyleto nullso that the splash screen does not animate the transition to the MainActivity:

然后使用可绘制文件作为背景创建一个主题。我使用background属性而不是windowBackground文章中建议的属性,因为background考虑了状态和导航栏,更好地将可绘制对象居中。我还设置windowAnimationStylenull使初始屏幕不会动画过渡到MainActivity

<resources>

    <!-- Base application theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <!-- Splash Screen theme -->
    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:background">@drawable/background_splash</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>

</resources>

Then declare your theme in the manifest for your SplashActivity:

然后在清单中为您声明您的主题SplashActivity

<activity android:name=".SplashActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

And finally all you have to do in your SplashActivityis start your MainActivity, and the splash screen will only show for as long as it takes for your app to configure:

最后,您要做的SplashActivity就是启动您的MainActivity,并且闪屏只会显示您的应用程序配置所需的时间:

public class SplashActivity extends AppCompatActivity {

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

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

回答by Mateusz Kaflowski

I have had similar problem. There was a blank loading screen (not even toolbar). Mu culprit was in the manifest in the MainActivity:

我有过类似的问题。有一个空白的加载屏幕(甚至没有工具栏)。Mu 罪魁祸首在 MainActivity 的清单中:

 android:launchMode="singleInstance"