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...
}
}
スプラッシュスクリーンを表示する時間に関して特定の制約がない場合、次の方法で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');
起動時に新しいスレッドを作成するのではなく、この記事で詳しく説明しているように、リソースの読み込みを待つ必要のないビューを作成する必要があります: 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
属性を使用します。また、スプラッシュスクリーンが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();
}
}
スプラッシュ画面のコードは正常に機能しますが、次のアクティビティを呼び出すときは、onCreate()で重いタスクにAsynctaskを使用します...
簡単にするために、スプラッシュアクティビティとメインアクティビティを組み合わせてみてはどうでしょうか。そうすることで、両方の長所を活用できます。つまり、データの初回準備中のスプラッシュスクリーンと、以前に準備されたときの迅速な起動です。ユーザーに何も待たせないことは、本当に良い形ではありません...
何かのようなもの:
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
}
}
同様の問題がありました。空白のロード画面がありました(ツールバーもありません)。 Muの犯人は、MainActivityのマニフェストにありました。
Android:launchMode="singleInstance"