web-dev-qa-db-ja.com

Androidロード中にスプラッシュ画面を表示

Androidアプリがあり、3秒間「スプラッシュスクリーン」が表示されます。その後、MainActivityがロードされます。

残念ながら、MainActivityの読み込みにはさらに4秒かかります。最初の起動時はさらに長くなります。ただし、アプリをロードすると、すべてがスムーズに実行されます。

スプラッシュスクリーンの表示中にMainActivityがロードされるようにするにはどうすればよいですか?全体が完全にロードされるまで画像を表示するだけです。 Async-Taskについて読んだことがありますが、どこに置くべきか、それを適切に使用する方法がわかりません。誰かが私を助けてくれますか?

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

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

    }

}
14
HorstB

スプラッシュスクリーンを表示する時間に関して特定の制約がない場合、次の方法で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');

13
TmKVU

起動時に新しいスレッドを作成するのではなく、この記事で詳しく説明しているように、リソースの読み込みを待つ必要のないビューを作成する必要があります: Splash Screens the Right Way

記事で述べたように、layer-listlayout 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属性を使用します。また、スプラッシュスクリーンがwindowAnimationStyleへの遷移をアニメーション化しないように、nullMainActivityに設定します。

<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();
    }
}
32
Bryan

スプラッシュ画面のコードは正常に機能しますが、次のアクティビティを呼び出すときは、onCreate()で重いタスクにAsynctaskを使用します...

0
Puneet Kumar

簡単にするために、スプラッシュアクティビティとメインアクティビティを組み合わせてみてはどうでしょうか。そうすることで、両方の長所を活用できます。つまり、データの初回準備中のスプラッシュスクリーンと、以前に準備されたときの迅速な起動です。ユーザーに何も待たせないことは、本当に良い形ではありません...

何かのようなもの:

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
    }

}
0
Theo Lassonder

同様の問題がありました。空白のロード画面がありました(ツールバーもありません)。 Muの犯人は、MainActivityのマニフェストにありました。

 Android:launchMode="singleInstance"
0