Android Launcher7.0首次数据加载逻辑_第1张图片    

Launcher3简介

  Laucnher3采用mv模式。 数据层为LauncherModel,采用异步加载方式读写数据。界面层为Launcher

(1~7     )       准备工作

(8~12   )      工作线程sWorkThread 执行任务LoadTask

(11~18 )      找到适配的xml配置文件

(17~ 27)      解析xml数据,存入到workScreens  favorites数据库


解析XML代码分析

解析各个标签Google采用了策略模式,各个节点都需要解析,但是只是解析方法不同,Google将解析逻辑抽调出来,采用策略模式,降低耦合性。
Android Launcher7.0首次数据加载逻辑_第2张图片
21 (1)拿到根据屏幕尺寸匹配出来的default_workspace_*x*.xml文件生成解析器XmlResourceParser (2)得到各个节点解析器对象集合 (3)循环调用parseAndAddNode开始解析节点

protected int parseLayout(int layoutId, ArrayList screenIds)            throws XmlPullParserException, IOException {        XmlResourceParser parser = mSourceRes.getXml(layoutId);        beginDocument(parser, mRootTag);        final int depth = parser.getDepth();        int type;        HashMap tagParserMap = getLayoutElementsMap();        int count = 0;        while (((type = parser.next()) != XmlPullParser.END_TAG ||                parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {            if (type != XmlPullParser.START_TAG) {                continue;            }            count += parseAndAddNode(parser, tagParserMap, screenIds);        }        return count;}

22

(1)得到节点标签名,拿到dw_phone_hotseat.xml id

(2)递归调用方法parseLayout 去解析 dw_phone_hotseat.xml

(3)解析container,screen属性存入到contentValues里面

(4)解析x,y属性存入到contentValues里面

(5)得到节点标签名,去map中得到ResolveParser对象

(6)存入screenId

    protected int parseAndAddNode(            XmlResourceParser parser,            HashMap tagParserMap,            ArrayList screenIds)                    throws XmlPullParserException, IOException {        if (TAG_INCLUDE.equals(parser.getName())) {            final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);            if (resId != 0) {                // recursively load some more favorites, why not?                return parseLayout(resId, screenIds);            } else {                return 0;            }        }        mValues.clear();        parseContainerAndScreen(parser, mTemp);        final long container = mTemp[0];        final long screenId = mTemp[1];        mValues.put(Favorites.CONTAINER, container);        mValues.put(Favorites.SCREEN, screenId);        mValues.put(Favorites.CELLX,                convertToDistanceFromEnd(getAttributeValue(parser, ATTR_X), mColumnCount));        mValues.put(Favorites.CELLY,                convertToDistanceFromEnd(getAttributeValue(parser, ATTR_Y), mRowCount));        TagParser tagParser = tagParserMap.get(parser.getName());        if (tagParser == null) {            if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());            return 0;        }        long newElementId = tagParser.parseAndAdd(parser);        if (newElementId >= 0) {            // Keep track of the set of screens which need to be added to the db.            if (!screenIds.contains(screenId) &&                    container == Favorites.CONTAINER_DESKTOP) {                screenIds.add(screenId);            }            return 1;        }        return 0;    }

24

(1)循环调用对象AppShortcutWithUriParser解析节点

protected class ResolveParser implements TagParser {        private final AppShortcutWithUriParser mChildParser = new AppShortcutWithUriParser();        @Override        public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,                IOException {            final int groupDepth = parser.getDepth();            int type;            long addedId = -1;            while ((type = parser.next()) != XmlPullParser.END_TAG ||                    parser.getDepth() > groupDepth) {                if (type != XmlPullParser.START_TAG || addedId > -1) {                    continue;                }                final String fallback_item_name = parser.getName();                if (TAG_FAVORITE.equals(fallback_item_name)) {                    addedId = mChildParser.parseAndAdd(parser);                } else {                    Log.e(TAG, "Fallback groups can contain only favorites, found "                            + fallback_item_name);                }            }            return addedId;        }    }

25

(1) 通过packageName,className属性名,得到包类名

(2-1) 如果解析出来的包类名不为空则通过包类名生成intent对象

(2-2)如果解析出来的包类名为空则调用invalidPackageOrClass方法

(3)调用addShortcut方法存入到favorites数据库

public long parseAndAdd(XmlResourceParser parser) {            final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);            final String className = getAttributeValue(parser, ATTR_CLASS_NAME);            if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {                ActivityInfo info;                try {                    ComponentName cn;                    try {                        cn = new ComponentName(packageName, className);                        info = mPackageManager.getActivityInfo(cn, 0);                    } catch (PackageManager.NameNotFoundException nnfe) {                        String[] packages = mPackageManager.currentToCanonicalPackageNames(                                new String[] { packageName });                        cn = new ComponentName(packages[0], className);                        info = mPackageManager.getActivityInfo(cn, 0);                    }                    final Intent intent = new Intent(Intent.ACTION_MAIN, null)                        .addCategory(Intent.CATEGORY_LAUNCHER)                        .setComponent(cn)                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);                    return addShortcut(info.loadLabel(mPackageManager).toString(),                            intent, Favorites.ITEM_TYPE_APPLICATION);                } catch (PackageManager.NameNotFoundException e) {                    Log.e(TAG, "Unable to add favorite: " + packageName + "/" + className, e);                }                return -1;            } else {                return invalidPackageOrClass(parser);            }        }

(1)通过uri属性名解析uri值

(2)通过uri生成Intent值

(3)调用addShortcut方法存入到favorites数据库

 protected long invalidPackageOrClass(XmlResourceParser parser) {            final String uri = getAttributeValue(parser, ATTR_URI);            if (TextUtils.isEmpty(uri)) {                Log.e(TAG, "Skipping invalid  with no component or uri");                return -1;            }            final Intent metaIntent;            try {                metaIntent = Intent.parseUri(uri, 0);            } catch (URISyntaxException e) {                Log.e(TAG, "Unable to add meta-favorite: " + uri, e);                return -1;            }            ResolveInfo resolved = mPackageManager.resolveActivity(metaIntent,                    PackageManager.MATCH_DEFAULT_ONLY);            final List appList = mPackageManager.queryIntentActivities(                    metaIntent, PackageManager.MATCH_DEFAULT_ONLY);            // Verify that the result is an app and not just the resolver dialog asking which            // app to use.            if (wouldLaunchResolverActivity(resolved, appList)) {                // If only one of the results is a system app then choose that as the default.                final ResolveInfo systemApp = getSingleSystemActivity(appList);                if (systemApp == null) {                    // There is no logical choice for this meta-favorite, so rather than making                    // a bad choice just add nothing.                    Log.w(TAG, "No preference or single system activity found for "                            + metaIntent.toString());                    return -1;                }                resolved = systemApp;            }            final ActivityInfo info = resolved.activityInfo;            final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);            if (intent == null) {                return -1;            }            ///M: ALPS02377365,intent is different with launched from "all apps list" {@            if ("com.android.gallery3d".equals(info.packageName)) {                intent.setPackage(null);            }            /// @}            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);            return addShortcut(info.loadLabel(mPackageManager).toString(), intent,                    Favorites.ITEM_TYPE_APPLICATION);        }
26

(1)将值存入到contentValues

(2)调用LauncherProvider类静态内部类DatabaseHelper.insertAndCheck存入到数据库

    protected long addShortcut(String title, Intent intent, int type) {        long id = mCallback.generateNewItemId();        mValues.put(Favorites.INTENT, intent.toUri(0));        mValues.put(Favorites.TITLE, title);        mValues.put(Favorites.ITEM_TYPE, type);        mValues.put(Favorites.SPANX, 1);        mValues.put(Favorites.SPANY, 1);        mValues.put(Favorites._ID, id);        if (mCallback.insertAndCheck(mDb, mValues) < 0) {            return -1;        } else {            return id;        }    }

解析完所有的标签存入到数据库以后。继续执行方法loadWorkSpace()读取数据库组sBgItemsIdMap,sBgWorkspaceItems,sBgAppWidgets,sBgFolders,sBgWorkspaceScreens。


       

更多相关文章

  1. Android webView 获取、设置 cookie的方法
  2. Android常用控件的使用方法
  3. MPAndroidChart的一些问题解决方法
  4. 解决IE apk变成zip:Android 手机应用程序文件下载服务器 配置解决
  5. Android EditText TextWatcher 回调方法参数说明
  6. android 连接数据库
  7. Android生成界面的两种方法:setContentView和inflate的区别
  8. Android 使用Canvas在图片上绘制文字的方法

随机推荐

  1. 把ffmpeg-0.11.1整合到android项目中
  2. Android点击EditText之外的地方隐藏键盘
  3. Android(安卓)Audio System 之二:AudioFli
  4. Android的内存优化管理
  5. (Android design)新闻资讯类android客户
  6. android中的空指针异常NullpointExcepito
  7. 设备管理应用程序的实现(Device Administr
  8. [Android]如何做一个崩溃率少于千分之三
  9. Android(安卓)关于没有处理异常导致应用
  10. linux android 真机测试