android7.x Launcher3 Source Parsing (3)---workspace and allapps loading process

Source: Internet
Author: User
Tags addall

Launcher Series Catalogue:
First, android7.x Launcher3 source Parsing (1)-Start process
Second, android7.x Launcher3 source Code Analysis (2)-Frame structure
Third, android7.x Launcher3 source Code Analysis (3)-workspace and AllApps loading process

The first two blogs analyze the Lancher's start-up and launcher frame structure, which will focus on analyzing the loading process of the interface.

1. Overall process

Let's start with a whole flowchart. (The picture can not be seen in the download or right click on the new page to view the picture)

Start with the Launcher.java OnCreate method,

protected void onCreate(Bundle savedinstancestate) {    ......//Establish Launcherappstate objectLauncherappstate.setapplicationcontext (Getapplicationcontext ());    Launcherappstate app = Launcherappstate.getinstance (); ......//Establish Launchermodel objectMmodel = App.setlauncher ( This);//Some other object initialization... setcontentview (r.layout.launcher); Setupviews ();if(!mrestoring) {if(Disable_synchronous_binding_current_page) {//If The user leaves launcher, then we should just load items asynchronously when                //They return.Mmodel.startloader (Pagedview.invalid_restore_page); }Else{//We only load the page synchronously if the user rotates (or triggers a                //configuration Change) while Launcher are in the foregroundMmodel.startloader (Mworkspace.getrestorepage ()); }    }    ......}

The focus calls the Startloader method of Launchermodel, Startloader inside, the most important thing is to start the Loadertask,mLoaderTask = new LoaderTask(mApp.getContext(), synchronousBindPage);

We then analyze the Loadertask run method.

 Public voidRun () {......Keep_running: {if(debug_loaders)Log.DTAG,"Step 1:loading Workspace"); Loadandbindworkspace ();if(mstopped)                {Break keep_running; } waitforidle ();//Second step                if(debug_loaders)Log.DTAG,"Step 2:loading all Apps");                Loadandbindallapps (); Waitforidle ();//Third step                if(debug_loaders)Log.DTAG,"Step 3:loading Deep Shortcuts");            Loadandbinddeepshortcuts (); }......}

Here are a few steps, loadAndBindWorkspace –> waitForIdle() , loadAndBindAllApps() waitForIdle() loadAndBindDeepShortcuts()
3 Step loading process inside are interspersed with waitforidle, this method is why?

Private void Waitforidle() {          ......synchronized(Loadertask. This) {Final LongWorkspacewaittime = debug_loaders? Systemclock.uptimemillis ():0; Mhandler.postidle (NewRunnable () { Public void Run() {synchronized(Loadertask. This) {mloadandbindstepfinished =true;if(debug_loaders) {LOG.D (TAG,"Done with previous binding step"); } loadertask. This. Notify (); }                        }                    }); while(!mstopped &&!mloadandbindstepfinished) {Try{//Just in case mflushingworkerthread changes and we aren ' t woken up,                        //Wait no longer than 1sec at a time                         This. Wait ( +); }Catch(Interruptedexception ex) {//Ignore}                }               ......            } }

The load data is handled in the UI thread, and the UI thread is normally not blocked, otherwise it is possible to generate ANR, which can seriously affect the user experience. All here Loadertask after the result is sent to the UI thread, in order to ensure that the interface binding task can be completed efficiently, it often pauses its own task and waits for the UI thread to finish processing.
Analysis of this method:
First, create a task that the UI thread performs at leisure, which is responsible for setting some key control flags and adding them to the processor's message queue via the Postidle method. Once the task is executed, the mloadandbindstepfinished is set to true to control the impending conditional infinite wait. Finally, set a conditional infinite wait, waiting for instructions from the UI thread.

2. Workspace loading Process

As can be seen from the general flowchart, the loading process of workspace is mainly divided into loadWorkspace();bindWorkspace(mPageToBindFirst);

A, Loadworkspace ()

Loadworkspace () The code is too much, here is not all out, the main function is responsible for reading data from the database table and translated into the data structure of the launcher desktop items.
Here are the steps:
1, carry out some pretreatment
2. Load Default values

LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary()

Before Launcher2 loadDefaultFavoritesIfNecessary This method, this is the way to load the default layout:

workspaceResId = sp.getInt(DEFAULT_WORKSPACE_RESOURCE_ID, R.xml.default_workspace);

But in Launcher3 , that's how it's loaded:

int workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT,                            "xml", partner.getPackageName());

This place, I don't understand for the time being, which is the default layout?

3. Initialize data
Empty the previous memory data

/** Clears all the sBg data structures */        privatevoidclearSBgDataStructures() {            synchronized (sBgLock) {                sBgWorkspaceItems.clear();                sBgAppWidgets.clear();                sBgFolders.clear();                sBgItemsIdMap.clear();                sBgWorkspaceScreens.clear();            }        }

4, Query ContentProvider, return the result set of Favorites table

Finalhashmap<string, integer> installingpkgs = Packageinstallercompat. getinstance (mContext). Updat Eandgetactivesessioncache ();FinalArraylist<long> Itemstoremove =NewArraylist<long> ();FinalArraylist<long> restoredrows =NewArraylist<long> ();FinalUri Contenturi = LauncherSettings.Favorites.CONTENT_URI;if(debug_loaders) LOG.D (TAG,"Loading model from"+ Contenturi);FinalCursor C = contentresolver.query (Contenturi,NULL,NULL,NULL,NULL);

5, according to different types, the data is saved to the corresponding ArrayList.
Types include the following:

ITEM_TYPE_APPLICATIONITEM_TYPE_SHORTCUTITEM_TYPE_FOLDERITEM_TYPE_APPWIDGETITEM_TYPE_CUSTOM_APPWIDGET

Save the data to a global variable based on the above types
Sbgitemsidmap,sbgworkspaceitemsm,sbgappwidgets,sbgfolders

In addition, if there are empty folders, empty screen, also delete, and finally, all the screen loaded into the global variable Sbgworkspacescreens.

......//Remove any empty folder                     for(LongFolderId:LauncherAppState.getLauncherProvider (). Deleteemptyfolders ()) {                        Sbgworkspaceitems.remove (Sbgfolders.get (FolderID));                        Sbgfolders.remove (FolderID);                    Sbgitemsidmap.remove (FolderID); } ... sbgworkspacescreens.addall (Loadworkspacescreensdb (Mcontext));//Remove any empty screensArraylist<long> Unusedscreens =NewArraylist<long> (Sbgworkspacescreens); for(ItemInfo Item:sbgitemsidmap) {LongScreenid = Item.screenid;if(Item.container = = LauncherSettings.Favorites.CONTAINER_DESKTOP && Unusedscreens.contai                    NS (Screenid)) {unusedscreens.remove (Screenid); }                }//If There is any empty screens remove them, and update.                if(Unusedscreens.size ()! =0) {Sbgworkspacescreens.removeall (unusedscreens);                Updateworkspacescreenorder (context, sbgworkspacescreens); }
B, Bindworkspace

The function of Bindworkspace is to display the data obtained above by launcher.
Steps:
1. Copy the data first:

            synchronized (sBgLock) {                workspaceItems.addAll(sBgWorkspaceItems);                appWidgets.addAll(sBgAppWidgets);                orderedScreenIds.addAll(sBgWorkspaceScreens);                folders = sBgFolders.clone();                itemsIdMap = sBgItemsIdMap.clone();            }

2. Loading data and sorting

            //装载桌面项数据            filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems,                    otherWorkspaceItems);            //装载widget                    filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets,                    otherAppWidgets);            //装载文件夹            filterCurrentFolders(currentScreenId, itemsIdMap, folders, currentFolders,                    otherFolders);            //排序                    sortWorkspaceItemsSpatially(currentWorkspaceItems);            sortWorkspaceItemsSpatially(otherWorkspaceItems);

3. Start binding

Just the last flowchart.

3. Loading of application Apps

Load the main process of the app, the top of the flowchart has been given, if all the apps are not loaded, then loadAllApps(); , or directlyonlyBindAllApps();

1, Loadallapps ()

According to the code, draw a flowchart, but I do not understand userprofile is a what ghost?

2, Onlybindallapps ()

The function here is much simpler than binding workspace, and notifies launcher binding directly

Runnable r =NewRunnable () { Public void Run() {Final Longt = Systemclock.uptimemillis ();FinalCallbacks callbacks = Trygetcallbacks (oldcallbacks);if(Callbacks! =NULL) {callbacks.bindallapplications (list);                    Callbacks.bindallpackages (widgetlist); }if(debug_loaders) {LOG.D (TAG,"Bound All"+ list.size () +"Apps from the cache in"+ (Systemclock.uptimemillis ()-T) +"MS"); }                }            };

Take a look at the function of launcher bindAllApplications , of course, this function is also in the Loadallapps function, that is, how to bind the data to display it?
The Launcher.java bindAllApplications function will set the data to Allappscontainerview.

ifnull) {            mAppsView.setApps(apps);        }

And then with the code to Allappscontainerview,

publicvoidsetApps(List<AppInfo> apps) {        mApps.setApps(apps);    }

Where does the apps work? The obvious is the onfinishinflate () function,

.....        // Load the all apps recycler view        mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);        mAppsRecyclerView.setApps(mApps);        mAppsRecyclerView.setLayoutManager(mLayoutManager);        mAppsRecyclerView.setAdapter(mAdapter);        mAppsRecyclerView.setHasFixedSize(true);.....

Set to Recyclerview, it is clear that the Launcher application interface is a custom Recyclerview, adpter for this recyclerview binding is Allappsgridadapter, Looking at this adpter onCreateViewHolder function, it is obvious that there are different layouts loaded depending on the type (app interface has apps and folders, there's a search box on the head, and this is the easiest to implement with Recyclerview). about how Recyclerview can load different layouts based on different types, you can refer to the different view implementations of the blog Recyclerview that I wrote a long time ago position load different.

Well, Launcher3 's workspace and application apps load the process, which will be followed by a detailed analysis of the contents of the launcher.

android7.x Launcher3 Source Parsing (3)---workspace and allapps loading process

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.