Symbian is an operating system widely used on mobile phones and mobile devices. Because mobile phones and PCs are different, there is no unified standard, its hardware configuration and user interfaces are significantly different (for example, some mobile phones do not have touch pens). Symbian provides basic services and a general UI Layer (uikon ), mobile phone manufacturers who have obtained Symbian authorization generally design their own user interfaces for their own mobile phones of specific models, it is famous for Nokia's Series 60 Platform (for Nokia 7650, Nokia N-Gage, Siemens SX1, etc.) and Sony
Ericssion's uiq platform (the uiq platform itself is the native UI of Symbian, but now Symbian sells it to Sony ericssion ). The former is a single-handed mobile phone with no touch screen or pen. Generally, there is a four-way navigation key, and the latter runs on a mobile phone with a large screen and a touch screen.
I. Module Analysis
Avkon is a UI Layer dedicated to s60 developed by Nokia on the Symbian uikon UI Layer. It is similar to MFC. The helloworld project is developed based on this framework.
First, each compiled GUI application (*. APP) is actually a multi-state DLL, not an executable module similar to EXE in the general sense. When an application is executed, osstransmits the appname as a token to apprun.exe, and apprun.exe creates an application process and loads *. app to the address space of the newly created process. Therefore, each app exports a function newapplication (), which is exported by serial number. Take the helloworld project as an example. Check the helloworld under the directory % sdkroot %/6.1/series60/epoc32/build/Symbian/6.1/series60/series60ex/helloworld/group/helloworld/wins. this can be seen in the def file. Newapplication's function body is in the helloworld. cpp file. It does a simple job. It is just a new chelloworldapplication object and returns its pointer. There is another global function e32dll in this file, which is equivalent to the dllmain function programmed by DLL in windows, which is the DLL entry
Point, where you can initialize TLS (Thread Local Storage). Every Symbian program must have this function. When the application is ready to run, e32dll will be called by the framework first, and the framework will pass in a parameter areason, which has four possible values: edllprocessattach, edllthreadattach, edllthreaddetach or edllprocessdetach, here, kerrnone is directly returned, indicating no error.
Next, we will analyze the application class chelloworldapplication. According to the official document, this class is "an application that creates the new blank document and defines the application uid", which means that this class is responsible for generating a blank document for new users, and define the UID of the application. This class has only two member functions: appdlluid and createdocumentl. Appdlluid returns only one pre-defined written uid. The createdocumentl function uses the this pointer of the chelloworldapplication application object to generate a new document object and chelloworlddocument (note: adding L to the function name indicates that this function can exit unexpectedly ). This application class does not provide constructors. According to the C ++ language specification, the compiler will generate a default constructor. I think, probably because the chelloworldapplication class does not add any data members (only two function members are added), you do not need to provide your own constructor to complete additional constructor actions. After tracing to its ancestor class ceikapplication, we can find that its constructor is protected, which is a typical feature constructed in two steps. By declaring the constructor as protected, you can prevent the user from bypassing two steps to construct a class C object (this small trick and dynamic in MFC
Create is the same), forcing users to generate objects through the static function newl or newlc.
Then there is the document class chelloworlddocument. The role of this class is "a document object that represents the data model and is used to construct the app UI". It feels a bit similar to the document class in MFC, represents data and creates the UI. First, constructor/destructor appear. This function is an empty function. The remaining three member functions newl/newlc and constructl are used to complete the two-step construction. The so-called two-segment structure is a concept introduced in Symbian. If the constructor and destructor of C ++ fail, an exception cannot be thrown, if you directly put a large amount of initialization code in the constructor, it will increase the chance of constructor failure. Once the constructor fails, it is difficult to clean up the "unfinished building" that has been abandoned halfway during the construction process. The two-step structure proposed by Symbian is to remove all the code that may cause failure from the constructl () function and put it in the member function constructl () after the constructl is executed, the constructl is called to complete subsequent construction actions to ensure that the constructor will never fail. This process is called "Two-Step Construction ". Related to this, some Symbian classes often add a pair of functions: newl and newlc to implement two-step construction. These two functions are declared static and recall the syntax definition of C ++, static member functions are actually independent from other classes. They can be called before any instance of the class exists, therefore, in Symbian, you can call these two functions explicitly to create a class instance. Let's take a look at the Code:
Chelloworlddocument * chelloworlddocument: newl (ceikapplication & AAPP) {chelloworlddocument * Self = newlc (AAPP); // The constructor is successfully constructed. The pointer is popped up from the cleanup stack, because there is no need to protect cleanupstack: Pop (Self); return self;} chelloworlddocument * chelloworlddocument: newlc (ceikapplication & AAPP) {chelloworlddocument * Self = new (eleave) chelloworlddocument (AAPP); // construct in the First Step // self points to an instance with half construction and pushes it into the cleanup stack to prevent subsequent Construction Failure cleanupstack: pushl (Self ); self-> constructl (); // construct return self in step 2 ;}
We can see that newl calls newlc. newlc first generates an instance of the chelloworlddocument object (this is the first step of construction, new has been overloaded, and eleave is its parameter, when new fails, it will exit abnormally), push the pointer into the cleanup stack, and then call constructl (constructed in step 2). The difference between newl and newlc is: newl creates an instance on the stack. When the memory is insufficient, it exits unexpectedly. newlc creates an instance on the stack and pushes it into the cleanup stack. If the memory is insufficient, the system exits unexpectedly. (Note: The suffix L indicates leave, indicating that it may exit abnormally and c Indicates cleanup.
Stack means that the objects created on the stack will be pushed to the cleanup stack ).
The last function is createappuil. This function creates the UI and returns a pointer to the UI object to the framework. It is worth noting that the construction process of the UI class is not constructed in two steps, after its constructor is called in createappuil, the Framework obtains the UI Object Pointer, and then the framework actively calls the constructl function of the UI class to complete all the construction work of the UI object, the ownership of the UI object is also transferred to the framework, so the document class does not otherwise destroy the UI object.
The first class is the UI class chelloworldappui. As mentioned above, the UI object is not constructed in two steps and does not provide newl and newlc functions. The official help described it as "an app UI (Application User Interface) object that handles the commands generated from menu options ". It can be seen that it is used to process USER command input. First, we analyze the constructl function. It first calls the baseconstructl () function of the base class to complete some work, such as reading resources. Then, create an instance of the View class in two steps (The View class is displayed on the screen, which will be described below). The View class is owned by the UI class, in the chelloworldappui class, a pointer member iappview points to the constructed view object. The View class destructor are completed in the UI class destructor. Finally, addtostackl (iappview) is called) add view object to control
Stack (when the UI object is destroyed, the view object must be taken from the Control Stack. For details, refer to the destructor of the chelloworldappui class ), this is to ensure that the application can respond to the user's key actions. As long as the view object is on the Control Stack, The offerkeyeventl function is called no matter when the user presses the key, this function has two parameters: key down, key press, or key up, And the encoding of the pressed button. Next we will talk about the main task of UI-processing user command input. This is done in the handlecommandl member function. The framework of this function is similar to that of Windows
The Window Function in SDK programming-a large switch structure, the overall structure is well understood, basically look at the context, several acommand definitions, such as ehelloworldcommand1 and eaknsoftkeyexit, are in helloworld. RSS (this is a resource file, a bit similar to the res file in VC), ehelloworldcommand1 refers to the "hello" menu item in the left soft key option pop-up menu, eaknsoftkeyexit refers to the "exit" menu item under "hello". The only difference is that eeikcmdexit does not find the definition, which may be pre-defined by the framework. _ DEFINE macro defines an instance message of the tlitc class and initializes it as the string given by the second parameter. Then a new cakninformationnote object is generated (the object functions like MessageBox ), displays the string in the message. In particular, there is a panic function in the last default Branch, which literally means "panic,
Panic code is probably the meaning of error code. This function is probably an error code returned, and ehelloworldbasicui = 1 is defined in the helloworld. Pan file.
The 4th categories are view classes used to display data on the screen. This class has a total of six member functions. constructor and destructor are used for the first step of construction. This is null. The functions of newl and newlc are not mentioned as mentioned above. The focus of our analysis is the draw function, which is similar to the onpaint function of MFC. The framework will call it when re-painting is required. programmers should not manually call it, because before calling draw, you must activate the (activated) system's GC (graphics context) -- similar to a concept of DC. What if we want to repaint the window? The answer is to use the drawnow function, which will inspire the framework to call draw. (Of course, it is also possible to manually call draw directly, but activategc must be performed first, and deactivategc should be executed after draw is finished ). The last thing to note is that the draw function is never allowed to exit abnormally (leave), because as mentioned earlier, the draw function is compiled by a programmer. During the program running, it may be automatically called by the Framework. If the draw function throws an exception to the framework, it is impossible for the framework to know what exceptions have occurred and how to handle the errors? Therefore, the draw function must use the trap macro to actively capture errors.
Ii. startup sequence
1. When an application is started, the Framework loads the application DLL (that is, the generated app file) and calls its e32dll function. This process is very similar to the process of loading the DLL in windows.
2. The Framework calls the newapplication function exported by the application DLL. This function creates an instance of the chelloworldapplication class, returns a pointer to the application object to the framework that calls it, and then the framework uses this pointer to complete subsequent creation of the application.
3. The Framework calls appdlluid to obtain the UID of the program. UID is used to check whether an instance is running in the program. If so, a new instance is not started again. Instead, it is switched to the running application.
4. The Framework calls the createdocumentl member function of chelloworldapplication. This function creates an instance of the document class and returns a pointer to the created document object. In this way, the framework can directly call the member functions of the document class. Here, the document class is created in two steps based on the Symbian OS, using the static member function newl of the document class.
5. The Framework calls appdlluid again to check whether files need to be loaded from the file system. The helloworld project has no associated files because it does not need to save any information persistently.
6. the Framework calls the createappuil function of the Document Object, creates a UI object, and obtains its pointer (note that the createappuil function is only a new UI object, that is, only the constructor of the UI object is called, according to the two steps of Symbian, the UI object has not been fully constructed ).
7. the Framework calls the constructl function of the UI object to construct the UI object. (here, the Framework calls the constructl and constructl functions of the UI object to construct the UI object, in this way, the framework can complete any necessary initialization work before the UI object is completely created.) In the constructl function, the base class baseconstructl function is called first, complete the work such as reading the resources associated with the application. Then, call the newl function of the View class to create the view object (constructed in two steps ).
8. The Framework calls the draw function of the view object. The draw function is displayed on a blank screen.
9. When the option menu is selected, the Framework calls the handlecommandl function of the UI object and passes an acommand parameter to the function to indicate which menu item the user selects. The UI performs corresponding actions for different menu items. The action here is to create an information note and display it.