32

We know that when the app do some long process like downloading some information from internet it could show a splash screen before loading the application and when the app is loaded completely it will display the main page. In splash screen activity we must load long processes in threads to avoid showing black screen before loading app. I had done all of them. but also the black screen appears before showing app. This is my onCreate method of the splash screen activity:

    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);
        }
    }

and this is the code of LoadApplication method:

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

I don't understand why the black screen appears and how should to avoid from this now. I have some code that access to storage in oncreate of my application class. Maybe the issue's root cause be from there.There fore i shared its 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.Long story short.Now the question is this-- Really what is the root cause of this black screen. Is this from splash activity or from application class. And How we can solve it and avoid form showing this?

TouchBoarder
  • 6,285
  • 2
  • 49
  • 60
Husein Behboudi Rad
  • 5,114
  • 10
  • 51
  • 110
  • If you don't set a custom theme with your own background for your application, the android default theme will be drawn with a black background first, before your background, see my answer. – TouchBoarder Jan 13 '13 at 22:11

7 Answers7

69

Add a theme with the background you are using to your application tag in the manifest file to prevent the black screen to be drawn.

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

Read why there is a black screen here On app launch, Android displays a simple preview window (based on your activity theme) as an immediate response to the user action. Then the preview window crossfades with your actual UI, once that has fully loaded. To ensure a smooth visual transition, your activity theme should match your full UI as closely as possible. The below image shows how the experience can be jarring if not handled properly.

TouchBoarder
  • 6,285
  • 2
  • 49
  • 60
  • It soulution resolve the problem. But have some issues. suppose that anybody wants to change the background of splash based on the site that client loads it's app. by this solution i can't change the background. – Husein Behboudi Rad Jan 14 '13 at 06:26
  • I think you are right.Async tasks and threads are similar to each other and the black screen that shows some little before showing app is not avoidable and there is one so;ution to avoid this is adding a custom theme to app or activity – Husein Behboudi Rad Jan 14 '13 at 07:50
  • I have a question, is this really how to treat this thing? I am currently working on the same issue. thanks! – CaffeineShots Oct 02 '13 at 09:46
51

This initial screen that you see is called the "Preview" screen. You can disable this completely by declaring this in your theme:

android:windowDisablePreview

<style name="Theme.MyTheme" parent="android:style/Theme.Holo">
    <!-- This disables the black preview screen -->
    <item name="android:windowDisablePreview">true</item>
</style>

An explanation of how to handle this screen is posted here: http://cyrilmottier.com/2013/01/23/android-app-launching-made-gorgeous/

mdupls
  • 1,962
  • 1
  • 24
  • 39
  • 7
    Quoted from article(link): "Unfortunately, disabling preview windows also removes their main advantage: simulate an instant application launching. As a result, I highly suggest you not to disable starting windows unless really necessary (this is mostly only necessary in games based on Open GL ES)." – TouchBoarder Nov 22 '13 at 22:21
  • Agreed. For me, the biggest problem was the label of the Activity showing up on this preview screen. This can be resolved by setting android:displayOptions=none in the theme for the Activity and then programmatically requesting a title through the getActionBar().setDisplayShowTitleEnabled(true); After this, the black screen is preferable. – mdupls Nov 25 '13 at 13:45
  • The simplest and easiest solution. I would prefer your solution over @mdupls solution – Jigar Apr 09 '15 at 04:55
  • 1
    @Jigar do you mean you prefer this over TouchBoarder's solution? – mdupls Apr 09 '15 at 15:21
  • Sorry I mean i would prefer you solution over @TouchBoarder solution – Jigar Apr 18 '15 at 07:06
  • The best solution! – valerybodak Apr 13 '16 at 16:03
  • This is the best solution – vishal dharankar Sep 25 '16 at 13:27
  • i prefer this solution this is the best solution. – Asesha George May 15 '17 at 15:43
  • I like this solution. truly the best and precise – Pavan Apr 12 '20 at 15:15
9

Add this line in your AndroidManifest.xml to the Launcher Activity:

android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen

gprathour
  • 13,193
  • 5
  • 56
  • 85
Vinutha YS
  • 133
  • 1
  • 7
2

You can solve this bug by converting image as a brush(color).

Add new file xml(splash_bg.xml) file in the drawable folder, like this.

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

Now add a new style, and apply splash_bg.xml as a background color.

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

Apply this new style to your main launcher activity or splash screen.

[Activity(Label = "label", MainLauncher = true, Theme = "@style/Theme.SplashBg")]
public class SplashScreenActivity : Activity
Maulik Parmar
  • 727
  • 9
  • 14
1

If you call some "heavy code" in onCreate the screen will appear black until it is done loading. You might consider using AsyncTask and make the onCreate handle setContentView etc, and make the AsyncTask handle "the heavy code".

Magakahn
  • 488
  • 7
  • 31
  • 1
    @HuseinBehbudiRad I think you commented the wrong question. Your comment fits the answear above ;) – Magakahn Jan 14 '13 at 14:29
1

the better solution to avoid this problem is using AsyncTask, here is a sample code that i use in one of my 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);

             } 
    }

and inside the onCreate Methode implement this:

            @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"));
        }
Harshad Pansuriya
  • 17,218
  • 7
  • 58
  • 86
0

Here's some food for thought; maybe you don't have a sizeable initialization delay in your application at all; you might in fact, be waiting for the instant run service.

From what I've experienced, the symptoms of this are that your application shows a lengthy black screen whilst initializing, but upon debugging you find that none of your Application/Activity's onCreate methods have yet to even be called whilst it's visible.

Community
  • 1
  • 1
Mapsy
  • 3,749
  • 1
  • 30
  • 42