As you already know, performance is a critical issue in any mobile solution. We have to take care of many things, but probably the more important aspect of any mobile development improvement, should be the UI responsiveness.
If the user press a button and wait for 15 seconds with no feedback until the action is finally done, he'll feel the sensation of something going wrong with the application, or probably the need to press the button again. Sometimes a good option is to initialize some load-expensive resources at start-time. The problem here is we already have performance expensive tasks while the application is being launched, and due to adding optimization tries we can found ourselves running an application which takes 20 seconds until the first form is show.
Here's where splash screens help us. It's radically different an application that only shows a wait cursor during 20 seconds until the first form appears than an application which shows the splash screen after 4 seconds letting the user know something is going on, and showing progress during the next 25 seconds even if it's taking more than the original 20 seconds. The key here is feedback, information. The user knows what is going on. He has information, he knows the application is already running, even if it still being loaded.
Add a splash screen to your mobile application can looks like a piece of cake, but it's not. There are three important guidelines that you should follow if you want to get the advantages of having a splash screen:
- It should be shown as soon as possible.
- Show the splash screen should be a light weight process.
- It should show progress (or activity at least).
As a .Net CF application usually starts showing a main form, it's recommendable to show the splash screen while the form is being initialized. As we've seen before, it should be a light weight process; ideally it should be as light as possible. A very good option is to create a very simple Splash Form and draw the splash screen directly overriding the OnPaint method. The Splash Form should be maximized (WindowState = Maximized) and totally empty (free of menus or controls).
Then, we can override OnPaintBackground leaving it empty to improve the performance (we don't need to paint a background here anyway), and draw the SplashScreen manually overriding OnPaint:
protected override void OnPaint(PaintEventArgs e)
{
Font font = new Font("Arial", 10, FontStyle.Bold);
if (backgroundBmp == null)
backgroundBmp = (Bitmap)Properties.Resources.ResourceManager.GetObject("SplashBitmap");
e.Graphics.DrawImage(backgroundBmp, 0, 0);
e.Graphics.DrawString("Splash Screen Sample", font, new SolidBrush(Color.Yellow), 37, 30);
e.Graphics.DrawString("http://www.mobilepractices.com", font, new SolidBrush(Color.White), 7, 50);
e.Graphics.DrawString("Loading...", font, new SolidBrush(Color.White), 65, 78); ShowProgress(0);
}
In this code, we're drawing the full splash screen, but the progress is painted in a different method called "ShowProgress". It will show the progress painting directly on the form graphics:
public void ShowProgress(int percentage)
{
Graphics gr = this.CreateGraphics();
gr.DrawRectangle(new Pen(Color.Black), new Rectangle(32, 95, barwidth, 12));
gr.FillRectangle(new SolidBrush(Color.Black), new Rectangle(32, 95, (barwidth * percentage) / 100, 12));
}
This method will update the progress quickly while your application is being initialized, without the need of paint the full splash screen for each update.
On the main form constructor on your application ("Form1.cs" in the sample code), you should create and show the splash form for first time, and let the system process the events (Application.DoEvents()) to get the splash visible. This will use OnPaint (and probably this will be the only time OnPaint is called) to draw the splash. From this point we'll use ShowProgress to update the splash showing progress, like in the following sample code (where thread.Sleep is used to simulate some expensive initialization tasks):
public void Initialize(SplashForm splash)
{
//Show the splash
splash.ShowProgress(30);
//... intialization first steps
Thread.Sleep(1000);
//... update splash
splash.ShowProgress(50);
//... some intialization steps ...
I'm including a sample application for Windows Mobile 6 Standard Edition (formerly Smartphone). Hope it helps: