繁体   English   中英

Android 在加载时显示启动画面

[英]Android display Splash-Screen while loading

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

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

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

启动画面.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);
    }
}

主活动.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...

    }

}

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

如文章所述,您应该创建一个可绘制的layer-list而不是layout XML 文件:

<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>

然后使用可绘制文件作为背景创建一个主题。 我使用background属性而不是文章中建议的windowBackground属性,因为background考虑了状态和导航栏,更好地将 drawable 居中。 我还将windowAnimationStyle设置为null以便初始屏幕不会动画过渡到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>

然后在您的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>

最后,您在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();
    }
}

如果没有关于应该显示初始屏幕的时间的特定限制,您可以通过以下方式使用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) {}
    }
}

如果结果数据的性质不同于字符串,您可以将Parcelable对象作为额外的活动添加到您的活动中。 onCreate您可以使用以下方法检索数据:

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

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

就像是:

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
    }

}

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

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

 android:launchMode="singleInstance"

就像在这篇文章中一样:https ://www.bignerdranch.com/blog/splash-screens-the-right-way/

1 - 为启动画面创建这样的 XML 布局。 我称之为“background_splash.xml”

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/cardview_light_background"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/kiss_com_sub_logo"/>
    </item>

</layer-list>

2 - 然后,转到styles.xml 并编写如下样式:

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
</style>

3 - 为您的飞溅写一个活动。 我称之为 SplashActivity.kt

package com.example.kissmoney

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity


class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
        finish()
    }
}

4 - 最后,转到您的 AndroidManifest.xml 并添加您的活动启动:(注意:不要删除 AndroidManifest 中的任何内容,只需将其添加到活动 Main 之前)。

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

这个做完了。 您无需担心应用程序需要启动的时间,飞溅将在那里停留足够的时间。 当您准备好 MainActivity 时,它将显示出来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM