Launcher is our home, which can be simply understood as a simplified Linux GUI. As a GUI, it must first complete its most essential functions,
That is, it must be able to provide categing to all applications (category_launcher). However, as a GUI, it must not only be a good score, but also be a beautiful girl (wallpaper );
In addition, it must be highly interactive. If there is no good interaction, just like you have been paying attention to a beauty for a long time, but she directly ignores it, the result is quite bad ~~
The so-called unknown, grain and grass first, before understanding the details of launcher, we need to complete some knowledge of literacy.
Of course, we can find this knowledge in Uncle SDK guide. I can tell you responsibly that if you have learned the three axes of Uncle SDK guide,
APK: You are basically invincible. The absolute armor is more than 10000. At least the basic knowledge is enough. Others are creative:
1. You must have a complete understanding of the four parts of the APK, especially the activity. Now you can simply understand that the activity is an application window.
2. You must understand the part of the UI. There are many content in this part. I usually see English as depressed, but if you want to design a beautiful girl or handsome guy that meets your aesthetic requirements, you must understand it,
You don't need to understand it completely, but at least there is a problem. You know which part to check ~~
3. resources can be used as an encyclopedia.
4. The intent part of the content also needs to be detailed. It is a channel for communication with applications. You can refer to the document written by James.
5. manifest is required. Check security.
6. The graphic part of the content is provided for GUI Design that requires better taste. Although it may be mainly used in the game, I think if you want to make a cool GUI, it must be 2D, 3D engine.
7. appwidget can be used as an example to read more information.
The prawns passing by must have been thundered by so much grain and grass. What we need to know in detail is 1 and 2. Others can be used as encyclopedias, but it would be best if you could see it carefully.
Well, everything is in trouble. Let's first look at who started this home. This part of knowledge can be skipped, but it is good to understand it,
You can understand how an APK process was born after October. The words mentioned below may be a little sour, so we suggest you first look at Android anatomy and physiology.pdf.
After Linux kernel is started, the app_main process will be used to initialize the android runtime Java Runtime Environment, while zygote is the first process of Android.
All Android applications and most system services are sub-processes that pass zygote fork. (I see that only the native service manager is not from zygote fork ).
Among several system services started in system server, we are related to the startup process.
After systerm server starts all services, the system enters the "System ready" status, and activity manager will be available.
Activity manager is a heavyweight service by looking at the code line. It mainly manages jumps between activities and the lifecycle of processes.
When activity manager finds that the system has been started, it sends an intent:
Intent intent = new intent (
Mtopaction,
Mtopdata! = NULL? Uri. parse (mtopdata): NULL );
Intent. setcomponent (mtopcomponent );
If (mfactorytest! = Systemserver. factory_test_low_level ){
Intent. addcategory (intent. category_home );
}
With the intent of the category type home, the activity manager will pass:
Startactivitylocked (null, intent, null, null, 0, ainfo,
Null, null, 0, 0, 0, false, false );
The home process is started. The process of starting the home process is actually a sub-process generated by using zygote fork.
Therefore, as long as the intent-filter is available in manifest, it can be started as home at startup:
<Intent-filter>
<Action Android: Name = "android. Intent. Action. Main"/>
<Category Android: Name = "android. Intent. Category. Home"/>
<Category Android: Name = "android. Intent. Category. Default"/>
</Intent-filter>
The switch between multiple home systems will have a choice at the beginning. As for this choice, it seems to be implemented by the Package Manager and has not been carefully studied.
Well, I learned how lancher is executed. Let's take a look at the internal structure of lancher. Let's take a look at how a lancher can be constructed to make it a reality:
1. Obtain all installed applications in the system and provide mappings that can run these applications (the image is a small icon of an application ). This is the skeleton of lancher,
What is lancher ~~ If it cannot provide access to the application, it will be a gorgeous vase.
2. to be better, we need to provide some pictures and a series of animated effects for this well-designed skeleton, that is, our wallpaper and a series of images,
Animation, graphic, and so on. If this is done, our home is basically shaped.
3. To make our GUI more user-friendly and easy to use, we also provide some additional features, such as the drag of icons implemented by lancher and shortcuts.
These are the things of benevolent and wise, depending on your design.
To sum up, A lancher contains three parts: application information collection, event processing, and animation. The following describes the implementation process of a launcher:
1. Design
Design your interface from the perspective of pure users, and write details as much as possible. Especially how application information appears,
And its operations are generally a good design highlight. Now we have a simple design. We need a wallpaper, and there is a bar control on the wallpaper to display our app icons.
After you select these icons, a graph is displayed in the middle of the screen to show the functions of the application. Then, click the graph to open the application.
2. Overall Design implementation
Design the overall implementation of the lancher based on your own ideas. If there is something that cannot be implemented, you must modify the design in time or change the design scheme.
Here we use a framelayout as our lancher container. Next layer, the bottom layer is used to place the shortcuts that may be needed and our wallpaper,
Then, put a self-defined component on the wallpaper layer to display our application information. I personally think framelayout is suitable for layout as a lancher,
It is similar to Photoshop's layer control, and the above layer will overwrite the following layer.
3. Specific implementation of specific functions
The specific code here is to design various Java function classes. Here is a simple description of wallpaper and drag-and-drop movement of icons. For more information, see the implementation of Android lancher.
Wallpaper generally registers a broadcastreceiver to process all the requests to change the background image in the system, and the drag-and-drop movement of icons involves the draglayer class.
We will focus on how to obtain information about installed Android applications. This involves another important service, which is the package manager,
It manages installed packages. Some permissions are involved here. I copied the permissions directly based on the implementation of Android lancher:
<Uses-Permission Android: Name = "android. Permission. call_phone"/>
<Uses-Permission Android: Name = "android. Permission. expand_status_bar"/>
<Uses-Permission Android: Name = "android. Permission. get_tasks"/>
<Uses-Permission Android: Name = "android. Permission. read_contacts"/>
<Uses-Permission Android: Name = "android. Permission. set_wallpaper"/>
<Uses-Permission Android: Name = "android. Permission. set_wallpaper_hints"/>
<Uses-Permission Android: Name = "android. Permission. Vibrate"/>
<Uses-Permission Android: Name = "android. Permission. write_settings"/>
Next let's take a look at the specific implementation. We create our own control and use linearlayout to load the imageswitcher and gallery controls,
Use gallery to display the obtained application information, use imageswitcher to display the application introduction, and click imageswitcher to open the corresponding application.
Public class mylancherswitcher extends linearlayout implements viewswitcher. viewfactory, adapterview. onitemselectedlistener, adapterview. onitemclicklistener {
Mimageswitcher = new imageswitcher (context );
Mgallery = new gallery (context );
This. addview (mimageswitcher, new linearlayout. layoutparams (layoutparams. wrap_content, 400 ));
This. addview (mgallery, new linearlayout. layoutparams (layoutparams. fill_parent, 80 ));
}
After the architecture is selected, the following describes how to provide information about the installed applications for the two controls. First, we obtain the Package Manager:
Packagemanager manager = This. getcontext (). getpackagemanager ();
The package manager then provides the corresponding application information through the intent information:
Intent mainintent = new intent (intent. action_main, null );
Mainintent. addcategory (intent. category_launcher );
Final list <resolveinfo> apps = manager. queryintentactivities (mainintent, 0 );
Collections. Sort (apps, new resolveinfo. displaynamecomparator (manager ));
Then we define our own class myappinfo to store the obtained information:
For (INT I = 0; I <count; I ++ ){
Myappinfo application = new myappinfo ();
Resolveinfo info = apps. Get (I );
Application. Title = info. loadlabel (manager );
Application. setactivity (New componentname (
Info. activityinfo. applicationinfo. packagename,
Info. activityinfo. Name ),
Intent. flag_activity_new_task
| Intent. flag_activity_reset_task_if_needed );
Application. Icon = info. activityinfo. loadicon (manager );
Mapplications. Add (application );
}
Final void setactivity (componentname classname, int launchflags ){
Intent = new intent (intent. action_main );
Intent. addcategory (intent. category_launcher );
Intent. setcomponent (classname );
Intent. setflags (launchflags );
}
We use an array to store the myappinfo information and provide it to gallery:
Private Static arraylist <myappinfo> mapplications;
Mgallery. setadapter (New applicationsadapter (this. getcontext (), mapplications ));
At last, the getview () function of arrayadapter <myappinfo> is reloaded to make some la s on the drawing, and the gallery will be able to display the image information of our application.
Finally, we pass the application information of the selected image in Gallery to imageswitcher, and register a key event for imageswithcher to start the application:
Private onclicklistener mimageswitcherlistener = new onclicklistener (){
Public void onclick (view v ){
If (mappinfo = NULL ){}
Else
V. getcontext (). startactivity (mappinfo. Intent );
}
};
In this way, we can basically solve the lancher skeleton, but there is another one, that is, when we install or delete an application, our home must capture this intent,
And timely adjust the application information in the home, so I want to register a broadcast receiver for the package for our control:
Private class applicationsintentreceiver extends broadcastreceiver {
@ Override
Public void onreceive (context, intent ){
Loadapplications (false );
}
}
Private void registerintentreceivers (){
Filter = new intentfilter (intent. action_package_added );
Filter. addaction (intent. action_package_removed );
Filter. addaction (intent. action_package_changed );
Filter. adddatascheme ("package ");
Registerreceiver (mapplicationsreceiver, filter );
}
OK, so our lancher is basically complete. The rest is to add the animation effect you need for each event. We will not talk about it here. I have never experienced Java programming before,
However, I personally think that programming for Android Java applications is relatively simple, but it is a little complicated because there are many things, but it is basically very convenient to use,
Basically, it is to overload or implement interfaces after inheritance, and Android provides a more convenient way for UI programming, that is, to use XML. XML can be used for your design more intuitively,
It also facilitates later modification and migration.