Android-classic launcher Main Menu module Learning

Source: Internet
Author: User

I believe that the Android system has seen the classic launcher. As shown in, it is the original launcher Main Menu function of 4.0. What we want to learn today is this. Through this small code, we can review the knowledge points:

①. Application acquisition and processing, including applications in SD.

②. Dynamically monitors the installation, uninstallation, and language system switching of user applications, such as switching from Chinese to English.

③. It is similar to the implementation of custom views of viewpager and pagerindicater. Note that it is similar, not the same.

④...

 

 

As we all know, If you directly export the source code of the system and directly import eclipse, an error will be reported. Let's take a look at the porting from the source code, just this module!

 

 

Let's take a look at the source code structure. As it is just a simple example, we have not considered the details too much. Please forgive me:

 

This app is the entry of the entire program. It inherits the application, where all applications are cached in the form of static variables, and broadcasts such as application addition, deletion, and change are registered, as well as the corresponding processing and notification of mainactivity, let's take a look at this most important class, where almost all the most important knowledge points are covered:

Public class app extends application {public static string tag = "way"; private broadcastreceiver mlauncherreceiver; static arraylist <applicationinfo> mapps; static final handlerthread sworkerthread = new handlerthread ("loadingapps "); static {sworkerthread. start ();} static final handler sworkerhandler = new handler (sworkerthread. getlooper (); static final handler shandler = new handler (); Private weakrefe Rence <mainactivity> mlauncher; @ overridepublic void oncreate () {super. oncreate (); registerrecever (); // register the application to add, delete, and broadcast getallapps ();}/*** register the application to add, delete, and other broadcasts */private void registerrecever () {// register receviermlauncherreceiver = new launcherreceiver (); intentfilter filter = new intentfilter (); filter. addaction (intent. action_package_added); filter. addaction (intent. action_package_removed); filter. addaction (inten T. action_package_changed); filter. adddatascheme ("package"); registerreceiver (mlauncherreceiver, filter); filter = new intentfilter (); filter. addaction (intent. action_external_applications_available); filter. addaction (intent. action_external_applications_unavailable); registerreceiver (mlauncherreceiver, filter); filter = new intentfilter (intent. action_locale_changed); registerreceiver (mlauncherreceiver, Filt Er);}/*** start the activity safely to prevent failed applications or permission issues ** @ Param intent * @ return */Public Boolean startactivitysafely (intent) {intent. addflags (intent. flag_activity_new_task); try {startactivity (intent); Return true;} catch (activitynotfoundexception e) {// toast. maketext (this, R. string. activity_not_found, // toast. length_short ). show (); log. E (TAG, "unable to launch intent =" + intent, e);} catch (securityex Ception e) {// toast. maketext (this, R. string. activity_not_found, // toast. length_short ). show (); log. E (TAG, "does not have the permission to launch intent =" + intent, e);} catch (exception e) {log. E (TAG, "catch exception", e);} return false;}/*** get all application information, for external calls ** @ return */Public arraylist <applicationinfo> getallapps () {If (mapps = NULL) {mapps = new arraylist <applicationinfo> (); fillallapps ();} r Eturn mapps;}/*** weak reference management main interface ** @ Param launcher */Public void setlauncher (mainactivity launcher) {This. mlauncher = new weakreference <mainactivity> (launcher);}/*** search all apps */private void fillallapps () {final intent mainintent = new intent (intent. action_main, null); mainintent. addcategory (intent. category_launcher); Final packagemanager = getpackagemanager (); List <resolveinfo> apps = pa Ckagemanager. queryintentactivities (mainintent, 0); If (mapps! = NULL) mapps. clear (); elsemapps = new arraylist <applicationinfo> (); For (resolveinfo app: Apps) {mapps. add (New applicationinfo (this, APP);} collections. sort (mapps, app_name_comparator); // sort by application name // sortappsbycustom (mapps); // custom sorting, if yes}/*** re-search all applications. When re-loading, call */private void refillallapps () {fillallapps ();} /*** find the application by package name ** @ Param packagename * package name * @ return */private list <resolveinfo> findactivitie Sforpackage (string packagename) {final packagemanager = getpackagemanager (); Final intent mainintent = new intent (intent. action_main, null); mainintent. addcategory (intent. category_launcher); mainintent. setpackage (packagename); final list <resolveinfo> apps = packagemanager. queryintentactivities (mainintent, 0); Return apps! = NULL? Apps: New arraylist <resolveinfo> () ;}/ *** Add the application with the specified package name, call ** @ Param packagename */private void addpackage (string packagename) {final list <resolveinfo> matches = findactivitiesforpackage (packagename) when the user installs the new application ); if (matches. size ()> 0) {for (resolveinfo info: matches) {mapps. add (New applicationinfo (this, Info) ;}}/*** remove the application with the specified package name, call ** @ Param packagename */private void removepackage (S Tring packagename) {for (INT I = mapps. size ()-1; I> = 0; I --) {applicationinfo info = mapps. get (I); Final componentname Component = info. intent. getcomponent (); If (packagename. equals (component. getpackagename () {mapps. remove (I) ;}}/ *** you can customize the application sorting method here, I have not called this function ** @ Param list */private void sortappsbycustom (list <applicationinfo> List) {int n = List. size (); // if no custom sorting table exists, sort by name for (INT I = 0; I <n; I + +) {Applicationinfo APP = List. get (I); app. index = I;} collections. sort (list, application_cust_sort);}/*** custom sorted comparator */static final comparator <applicationinfo> application_cust_sort = new comparator <applicationinfo> () {public final int compare (applicationinfo A, applicationinfo B) {return. index-B. index ;}};/*** comparator sorted by application name */static final comparator <applicationinfo> app_name_compar Ator = new comparator <applicationinfo> () {public final int compare (applicationinfo A, applicationinfo B) {int result = collator. getinstance (). compare (. title. tostring (), B. title. tostring (); If (result = 0) {result =. componentname. compareto (B. componentname) ;}return result ;}}; /*** tasks for processing application updates * include adding, deleting, updating, and changing languages **/private class packageupdatedtask implements runnable {public static final int op_none = 0; // unknown state public static final int op_add = 1; // Add the application public static final int op_update = 2; // update the application public static final int op_removed = 3; // remove the application public static final int op_reload = 4; // reload, for example, int MOP; string [] mpackages; Public packageupdatedtask (INT op, string [] packages) {Mop = op; mpackages = packages;} public packageupdatedtask (int op) {Mop = op ;}@ overridepublic void run () {If (Mop = op_reload) {Refillallapps ();} else {final string [] packages = mpackages; Final int n = packages. length; Switch (MOP) {Case op_add: If (n> 0) {shandler. post (New runnable () {@ overridepublic void run () {for (INT I = 0; I <n; I ++) {log. D (TAG, "packageupdatedtask add packagename =" + packages [I]); addpackage (packages [I]);} shandler. post (New runnable () {@ overridepublic void run () {mainactivity launcher = mlauncher. get (); If (launcher! = NULL) {launcher. bindallapps (); // callback main interface update }}) ;});} break; Case op_removed: If (n> 0) {shandler. post (New runnable () {@ overridepublic void run () {for (INT I = 0; I <n; I ++) {log. D (TAG, "packageupdatedtask remove packagename =" + packages [I]); removepackage (packages [I]);} shandler. post (New runnable () {@ overridepublic void run () {mainactivity launcher = mlauncher. get (); If (launcher! = NULL) {launcher. bindallapps (); // callback main interface update }}) ;}});} break; Case op_update: // update, not processed here (INT I = 0; I <n; I ++) {log. D (TAG, "packageupdatedtask update packagename =" + packages [I]);} break ;}}} private class launcherreceiver extends broadcastreceiver {@ overridepublic void onreceive (context, intent intent) {final string action = intent. getaction (); log. D (TAG, "launcherreceiver onrecive action = "+ Action); // broadcast if (intent. action_package_added.equals (Action) | intent. action_package_changed.equals (Action) | intent. action_package_removed.equals (Action) {final string packagename = intent. getdata (). getschemespecificpart (); Final Boolean replacing = intent. getbooleanextra (intent. extra_replacing, false); log. D (TAG, "launcherreceiver onrecive packagename =" + packagename); int op = PACKA Geupdatedtask. op_none; If (intent. action_package_changed.equals (Action) {op = packageupdatedtask. op_update;} else if (intent. action_package_removed.equals (Action) {If (! Replacing) OP = packageupdatedtask. op_removed;} else if (intent. action_package_added.equals (Action) {If (! Replacing) OP = packageupdatedtask. op_add;} If (op! = Packageupdatedtask. op_none) {sworkerhandler. post (New packageupdatedtask (OP, new string [] {packagename}) ;}} else if (intent. action_external_applications_available.equals (Action) {// broadcast available for the SD card application, where your application is installed in the SD card string [] packages = intent. getstringarrayextra (intent. extra_changed_package_list); sworkerhandler. post (New packageupdatedtask (packageupdatedtask. op_add, packages);} else if (intent. action_external_applications_unavailable.equals (Action) {// broadcast string [] packages = intent available for the SD card application. getstringarrayextra (intent. extra_changed_package_list); sworkerhandler. post (New packageupdatedtask (packageupdatedtask. op_removed, packages);} else if (intent. action_locale_changed.equals (Action) {// broadcast sworkerhandler in the system switching language. post (New packageupdatedtask (packageupdatedtask. op_reload ));}}}}

Applicationinfo is actually a JavaBean, but not all of it. It also has a special feature, that is, it processes the icons of all applications so that the application icons displayed in front of us are not uneven, or the difference is too big, which is worth learning. Let's take a look. The focus is on the application icon processing tool class below.

Public class applicationinfo {public charsequence title; // Application name public bitmap iconbitmap; // application icon public intent; // application intentpublic componentname; // application package name intindex; private packagemanager mpackagemanager; private context mcontext; Public applicationinfo (context, resolveinfo info) {mcontext = context; mpackagemanager = context. getpackagemanager (); this. componentname = new componentname (info. activityinfo. applicationinfo. packagename, info. activityinfo. name); this. title = info. loadlabel (mpackagemanager); this. iconbitmap = loadicon (Info); intent = new intent (intent. action_main); intent. addcategory (intent. category_launcher); intent. setcomponent (componentname); intent. setflags (intent. flag_activity_new_task | intent. flag_activity_reset_task_if_needed); this. intent = intent;} private bitmap loadicon (resolveinfo info) {Bitmap bitmap = bitmaputility. createiconbitmap (info. activityinfo. loadicon (mpackagemanager), mcontext); Return bitmap ;}} /*** this is an application icon processing tool class * @ author way **/final class bitmaputility {Private Static int siconwidth =-1; Private Static int siconheight =-1; private Static int sicontexturewidth =-1; Private Static int sicontextureheight =-1; Private Static final rect soldbounds = new rect (); Private Static final canvas scanvas = new canvas (); static {scanvas. setdrawfilter (New paintflagsdrawfilter (paint. dither_flag, paint. filter_bitmap_flag);} Private Static void initstatics (context) {final resources Resources = context. getresources (); siconwidth = siconheight = (INT) resources. getdimension (Android. r. dimen. required); sicontexturewidth = sicontextureheight = siconwidth;} static bitmap createiconbitmap (drawable icon, context) {synchronized (scanvas) {// we share the statics if (siconwidth =-1) {initstatics (context);} int width = siconwidth; int Height = siconheight; If (icon instanceof paintdrawable) {paintdrawable painter = (paintdrawable) icon; painter. setintrinsicwidth (width); painter. setintrinsicheight (height);} else if (icon instanceof bitmapdrawable) {// ensure the bitmap has a density. bitmapdrawable = (bitmapdrawable) icon; Bitmap bitmap = bitmapdrawable. getbitmap (); If (bitmap. getdensity () = bitmap. density_none) {bitmapdrawable. settargetdensity (context. getresources (). getdisplaymetrics ();} int sourcewidth = icon. getintrinsicwidth (); int sourceheight = icon. getintrinsicheight (); If (sourcewidth> 0 & sourceheight> 0) {// There are intrinsic sizes. if (width <sourcewidth | height <sourceheight) {// It's too big, scale it down. final float ratio = (float) sourcewidth/sourceheight; If (sourcewidth> sourceheight) {Height = (INT) (width/ratio);} else if (sourceheight> sourcewidth) {width = (INT) (height * Ratio) ;}} else if (sourcewidth <width & sourceheight 

After all the applications are installed, the rest is displayed on the main interface. Naturally, the mainactivity:

Public class mainactivity extends activity {private app mscenelauncherapplication; private sceneallappspagedview msceneallapps; @ overrideprotected void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. scene_allapps); mscenelauncherapplication = (APP) getapplication (); mscenelauncherapplication. setlauncher (this); initview (); bindallapps ();}/*** bind all applications */publ IC void bindallapps () {msceneallapps. setapps (mscenelauncherapplication. getallapps ();}/*** initialize view */private void initview () {msceneallapps = (sceneallappspagedview) findviewbyid (R. id. scene_allapps);}/*** process application click callback * @ Param v */Public void onappsitemclick (view v) {final applicationinfo info = (applicationinfo) v. gettag (); If (info! = NULL) {mscenelauncherapplication. startactivitysafely (info. intent) ;}@ overridepublic Boolean oncreateoptionsmenu (menu) {// inflate the menu; this adds items to the action bar if it is present. getmenuinflater (). inflate (R. menu. main, menu); Return true ;}}

I believe that if only some applications are displayed, this is very simple and can be implemented by many people. However, for example, system applications, he will consider many details, for example, Cache Optimization, thread security, application icon optimization, and Icon clicking effect are all worth learning. Other classes are custom views, there is a need for children's shoes can download the source code look: http://download.csdn.net/detail/weidi1989/5927283

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.