Android 7.0 高通平台原生Launcher3未读角标更新流程

来源:互联网 发布:淘宝商品点击排名 编辑:程序博客网 时间:2024/06/15 02:36

                                                            Android7.0 高通平台原生Launcher3未读角标更新流程

                                                                              --唐旋凯 2017.11.2

做2代项目的时候,图标的未读提示功能是自己写的,所以流程都很清楚,做3代的时候发现7.0的原生launcher已经支持了未读提示的功能,也没去看过它的原理,前几天研究未读提示动画的时候,看了下原生launcher未读图标的更新流程,写个文档记录下。

 

7.0高通原生的Launcher3分了两个情况来处理未读提示。

第一个情况是在Launcher3刚启动的时候,在Launcher.java的onCreate函数里直接绑定了高通用于处理未读提示的launcherunreadservice(其实进入这个servervice的源码里可以看到高通也只是支持了电话、短信、邮件3个应用的未读提示,而且也是通过查询监听这3个应用的数据库来获取数据的),

    private Map mUnreadAppMap = new HashMap<ComponentName, Integer>();    private ServiceConnection mConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            IGetUnreadNumber iGetUnreadNumber = IGetUnreadNumber.Stub.asInterface(service);            try {                if(iGetUnreadNumber != null){                    mUnreadAppMap = iGetUnreadNumber.GetUnreadNumber();                }            } catch (RemoteException ex) {            }            mIconCache.setUnreadMap(mUnreadAppMap);            unbindService(mConnection);        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };


可以看到通过这个service的接口函数,我们可以直接取得包含了应用包名和未读条数的map,然后再设置mIconCahe.setUnreadMap(……)来让launcher显示有未读提示的图标。为什么通过mIconCahe.setUnreadMap就能显示有未读提示的图标,因为在生成桌面图标的时候会通过未读提示count的数量来判断是否生成带有提示的图标。IconCaha.java –> cacheLocked(…)-> entry.icon =Utilities.createBadgedIconBitmap(…)

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public static Bitmap createBadgedIconBitmap(            Drawable icon, UserHandleCompat user, Context context, int count ) {        float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?                1 : IconNormalizer.getInstance().getScale(icon, null);        Bitmap bitmap = createIconBitmap(icon, context, scale);        // create the unread icon's info here        if (isUnreadCountEnabled(context) && count > 0) {            bitmap = createIconBitmapUnreadInfo(context, bitmap, count);        }        return badgeIconForUser(bitmap, user, context);    }


进入函数我们可以看到,通过判断count是否大于0来分别生成是否带有提示的图标。这是Launcher刚启动时就能显示未读提示图标的的流程。

     第二种情况是在Launcher启动之后,如果数据变化了如何实时更新相应的图标。在第一种情况的时候已经说了,launcherunreadservice这个服务其实就是用于查询和监听电话、短信、邮件这几个应用的数据库的,当这几个数据库的未读字段发生变化的时候,他就会发送一个带相应参数的广播出来,Launcher只要负责监听这个广播,

"com.android.launcher.action.UNREAD_CHANGED"

然后做出相应的处理就可以了。在LauncherModel.java-> onReceive(…)对这个广播进行了监听:

        } else if (ACTION_UNREAD_CHANGED.equals(action)) {            ComponentName componentName = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);            int unreadNum = intent.getIntExtra(EXTRA_UNREAD_NUMBER, 0);            if (componentName == null) return;            synchronized (mUnreadChangedMap) {                mUnreadChangedMap.put(componentName, new UnreadInfo(componentName, unreadNum));            }            sWorker.removeCallbacks(mUnreadUpdateTask);            sWorker.post(mUnreadUpdateTask);        }


可以看到接收到更新的广播后,主要图标更新工作都是UnreadUpateTask这个进程完成,这个函数得代码有点多,就不贴了,主要流程就是会走到AllAppList.java的unreadNumbersChanged(..)函数里,这个函数得作用就是把旧的图标移除,然后获取到一个重新画好角标的图标换上去。代码接着走下去就是调用callback函数通知workspace更新下桌面图标。这样新的数据就更新成功了.  

     7.0高通未读角标的更新流程基本就是这样。也没有对第三方应用做出支持。

原创粉丝点击