Nous savons que lorsque l'application effectue un long processus comme le téléchargement d'informations sur Internet, elle peut afficher un écran de démarrage avant de charger l'application et lorsque l'application est complètement chargée, elle affichera la page principale. Dans l'activité de l'écran de démarrage, nous devons charger de longs processus dans les threads pour éviter d'afficher un écran noir avant de charger l'application. Je les avais toutes faites. mais aussi l'écran noir apparaît avant d'afficher l'application. Voici ma méthode onCreate de l'activité de l'écran de démarrage:
protected override void OnCreate (Bundle bundle)
{
try {
base.OnCreate (bundle);
//_dt = DateTime.Now.AddSeconds (_splashTime);
SetContentView (Resource.Layout.Splash );
FirstLoadPB= FindViewById <ProgressBar >(Resource .Id.FirstLoadPB );
FirstLoadingInfo= FindViewById <TextView >(Resource .Id.FirstLoadInfo );
LoadApplication ();
} catch (System.Exception ex) {
Common.HandleException (ex);
}
}
et voici le code de la méthode LoadApplication
:
public void LoadApplication()
{
new System.Threading.Thread (new ThreadStart (() =>
{
//Some Codes to load applications- Downloading from web and accessing the storage(Because was many codes - about 100 line- i was clear them.
}
)
).Start ();
}
Je ne comprends pas pourquoi l'écran noir apparaît et comment éviter cela maintenant. J'ai du code qui accède au stockage dans une création de ma classe d'application. Peut-être que la cause principale du problème vient de là.Par conséquent, j'ai partagé son code:
public override void OnCreate ()
{
try {
base.OnCreate ();
_typeOfShow = new MapViewType ();
ListingTypes = new Dictionary<int,ListingTypeItem> ();
OfflineMode =false;
PropertyShowWasShown = false;
MeasutingUnitsChanged =false;
if(RplXmlSettings .Instance .getVal (AppConstants .XmlSettingShowOnCurrentLocationKey )== "True")
typeOfShow .ShowOnCurrentLocation =true ;
else
typeOfShow .ShowOnCurrentLocation =false;
//StorageClass .ctx = ApplicationContext ;
FillDashboardOnResume =false;
//initlize image loader
ImageLoader = Com.Nostra13.Universalimageloader.Core.ImageLoader.Instance;
Options = new DisplayImageOptions.Builder ()
.ShowImageForEmptyUri (Resource.Drawable.ic_tab_map)
.CacheOnDisc ()
.CacheInMemory ()
.ImageScaleType (ImageScaleType.InSampleInt)
.BitmapConfig (Bitmap.Config.Rgb565)
.Displayer (new FadeInBitmapDisplayer (300))
.Build ();
ImageLoaderConfiguration config;
ImageLoaderConfiguration .Builder builder =new ImageLoaderConfiguration
.Builder (ApplicationContext).ThreadPoolSize (3);
if(RplXmlSettings .Instance .getVal (AppConstants .XmlSettingMemoryCacheKey )== "True")
builder .ThreadPriority (4).MemoryCacheSize (1500000) ;// 1.5 Mb
builder .
DenyCacheImageMultipleSizesInMemory ().
DiscCacheFileNameGenerator (new Md5FileNameGenerator ()).
MemoryCache (new WeakMemoryCache()).
DiscCacheSize (15000000);
config = builder .Build ();
ImageLoader.Init (config);
} catch (Exception ex) {
Common .HandleException (ex);
}
}
OK.Longue histoire.Maintenant, la question est la suivante: quelle est vraiment la cause profonde de cet écran noir. Est-ce de l'activité splash ou de la classe d'application. Et comment pouvons-nous le résoudre et éviter que le formulaire ne le montre?
Ajoutez un thème avec l'arrière-plan que vous utilisez à votre balise d'application dans le fichier manifeste pour empêcher l'écran noir d'être dessiné.
theme.xml
<resources>
<!-- Base application theme is the default theme. -->
<style name="Theme" parent="Android:style/Theme" />
<style name="Theme.MyAppTheme" parent="Theme">
<item name="Android:windowNoTitle">true</item>
<item name="Android:windowContentOverlay">@null</item>
<item name="Android:windowBackground">@drawable/my_app_background</item>
</style>
</resources>
AndroidManifest.xml
....
<application
Android:name="@string/app_name"
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/Theme.MyAppTheme"
>
....
Cet écran initial que vous voyez s'appelle l'écran "Aperçu". Vous pouvez désactiver cela complètement en le déclarant dans votre thème:
Android:windowDisablePreview
<style name="Theme.MyTheme" parent="Android:style/Theme.Holo">
<!-- This disables the black preview screen -->
<item name="Android:windowDisablePreview">true</item>
</style>
Une explication sur la façon de gérer cet écran est publiée ici: http://cyrilmottier.com/2013/01/23/Android-app-launching-made-gorgeous/
Ajoutez cette ligne dans votre AndroidManifest.xml
à l'activité du lanceur:
Android:theme="@Android:style/Theme.Translucent.NoTitleBar.Fullscreen
Vous pouvez résoudre ce bogue en convertissant l'image en pinceau (couleur).
Ajoutez un nouveau fichier xml (splash_bg.xml) dans le dossier dessinable, comme ceci.
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item>
<color Android:color="@color/splash_bg_color"/>
</item>
<item>
<bitmap
Android:src="@drawable/splash_screen"
Android:tileMode="disabled"
Android:gravity="center"/>
</item>
</layer-list>
Ajoutez maintenant un nouveau style et appliquez splash_bg.xml comme couleur d'arrière-plan.
<style name="Theme.SplashBg" parent="Android:Theme">
<item name="Android:windowBackground">@drawable/splash_bg</item>
<item name="Android:windowNoTitle">true</item>
<item name="Android:windowContentOverlay">@null</item>
</style>
Appliquez ce nouveau style à votre activité de lancement principale ou à votre écran de démarrage.
[Activity(Label = "label", MainLauncher = true, Theme = "@style/Theme.SplashBg")]
public class SplashScreenActivity : Activity
la meilleure solution pour éviter ce problème est d'utiliser AsyncTask, voici un exemple de code que j'utilise dans l'un de mes ListActivity:
private class YoutubeTask extends AsyncTask<URL, Integer, String> {
protected void onPreExecute() {
super.onPreExecute();
mLoadingProgress.startAnimation(mDisappear);
mLoadingProgress.setVisibility(View.GONE);
showDialogProgress();
}
protected String doInBackground(URL... url) {
youtubeData = VersionParser.readFromUrl(url[0]);;
try {
JSONObject jsono = new JSONObject(youtubeData);
JSONObject feed = jsono.getJSONObject("feed");
JSONArray entry = feed.getJSONArray("entry");
for(int i = 0 ; i < entry.length() ; i++ ){
JSONObject item = entry.getJSONObject(i);
JSONArray AUTHOR = item.getJSONArray(TAG_AUTHOR);
JSONObject Author = AUTHOR.getJSONObject(0);
JSONObject author = Author.getJSONObject("name");
String author_name = author.getString(TAG_TITRE);
JSONObject Statistics = item.getJSONObject("yt$statistics");
String Views = Statistics.getString(TAG_VIEWS);
JSONObject Media = item.getJSONObject("media$group");
JSONObject MediaTitle = Media.getJSONObject("media$title");
String title = MediaTitle.getString(TAG_TITRE);
JSONObject DURATION = Media.getJSONObject("yt$duration");
String duration = DURATION.getString(TAG_DURATION);
JSONArray Thumbinail = Media.getJSONArray("media$thumbnail");
JSONObject IMAGE = Thumbinail.getJSONObject(0);
String image = IMAGE.getString(TAG_CONTENT);
String id = image.substring(22,33);
map = new HashMap<String, String>();
map.put(TAG_TITRE , title );
map.put(TAG_ID , id );
map.put(TAG_DURATION , duration );
map.put(TAG_IMAGE , image);
map.put(TAG_VIEWS , Views );
map.put(TAG_AUTHOR , author_name);
CURRENCY.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
dismisDialogProgress();
mListView.setVisibility(View.VISIBLE);
mListView.startAnimation(mAppear);
mAdapter = new MAdapter(youtubeSearch.this , CURRENCY);
mListView.setSelector(R.drawable.home_bg);
mListView.setAdapter(mAdapter);
}
}
et à l'intérieur de la méthode onCreate implémentez ceci:
@Override
public void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT < 11)
setTheme(Android.R.style.Theme_Black_NoTitleBar);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new YoutubeTask().execute(new URL("https://gdata.youtube.com/feeds/api/videos?q=Adele&max-results=15&v=2&alt=json"));
}
Si vous appelez un "code lourd" dans onCreate, l'écran apparaîtra en noir jusqu'à ce qu'il soit terminé de charger. Vous pourriez envisager d'utiliser AsyncTask et de créer la poignée onCreate setContentView, etc., et de faire de la poignée AsyncTask "le code lourd".
Voici quelques pistes de réflexion; peut-être que vous ne faites pas avez un retard d'initialisation important dans votre application; vous pourriez en fait être en attente du service d'exécution instantanée.
D'après ce que j'ai vécu, les symptômes de ceci sont que votre application affiche un long écran noir lors de l'initialisation, mais lors du débogage, vous constatez qu'aucun de vos Application
/Activity
's onCreate
méthodes doivent encore être appelées tant qu'il est visible.