精华内容
下载资源
问答
  • 隐藏任务栏图标

    千次阅读 2006-04-26 20:13:00
    关于本软件 本作品我业余完成,虫子自然少不了,如果不影响正常... 本作品还是个半成品,虽然已经有主要功能,但是仍需要改进。等我有空时候继续添加和完善吧。本软件运行平台为windows xp,windows 2

    关于本软件
        本作品是我业余完成的,虫子自然是少不了的,如果不影响正常的使用,这些虫子就不除了。呵呵~~。
        本人平时没什么特别爱好,就是看看书,写写程序,研究下技术,自然也乐在其中。本程序就是练习之作。有事没事,写写代码,就当作练字吧!
        本作品还是个半成品,虽然已经有主要功能,但是仍需要改进。等我有空的时候继续添加和完善吧。本软件运行的平台为windows xp,windows 2000,windows 2003。
        本人email:eboyspdg@163.com,如果有好的建议,可以给我email。如果有乐于技术研究的朋友跟我交流,也是欢迎之极。
        最新的软件更新情况请到 http://blog.csdn.net/bestpdg/archive/2006/04/26/678656.aspx ,这是我在csdn的blog,欢迎光临。
        下载地址: http://www.tiner.cn/HideProcess.rar
       
    关于使用
        程序运行后在左上角有个图标,你可以把图标拖动到任意的地方,鼠标右键点击该图标会弹出主界面,在进程列表中点右键可以进行隐藏等操作,而在隐藏进程列表中,点右键可以进行图标还原(从列表中删除)等操作。托盘目前只有隐藏操作而没有还原操作,图标也只是进程的图标而不是窗口的图标。

    更新情况
        4-29:昨天晚上(4-28)从10点边看电视边写代码,一直忙到凌晨1点多,增加了一个很Cool的功能,相信大家会喜欢的。这个功能5-1后再开放吧。
        5-11:放假几天,完善了桌面切换功能,支持新建桌面、桌面改名、自定义快捷键、鼠标快速切换(鼠标移动右下角区域就切换到默认桌面)、快捷键切换桌面,这样就算老板来了,你也可以快速隐藏,嘿嘿~~你可以再研究、工作、娱乐等界面快速切换,很cool的功能。上一个版本中,任务栏隐藏的图标,当该窗口被激活时,图表在任务栏那里会闪烁,现在用钩子和subclass解决了。希望大家喜欢,软件还在完善中.......

    展开全文
  • 任务栏程序-01

    千次阅读 2005-01-17 20:39:00
    打算分两次写成一个列于桌面右侧sidebar(中文名不知道叫什么,好像应该算是任务栏,因为主要灵感来自于Desktop Sidebar)程序,可以从网上读取天气预报,可以显示当前时钟等基本功能(你可以加入自己的功能)。...

    这里的人气真是不旺啊,我来添一把柴,希望能够带动大家的编程热情。这是我第一次写教程,不足之处大家多包涵。打算分两次写成一个列于桌面右侧的sidebar(中文名不知道叫什么,好像应该算是任务栏,因为主要灵感来自于Desktop Sidebar)程序,可以从网上读取天气预报,可以显示当前的时钟等基本功能(你可以加入自己的功能)。我的编程环境是Windows 2003 + Delphi 7,其他版本的delphi和windows我想都是没有问题的,演示请看附件。我想读者应该会一点Delphi,分两次主要是照顾一些初学者。OK, Let's go!

    //-----------正文开始-------------------

    不知到大家注意到没有?其实桌面(Desktop)和form1一样都是窗体(Window),区别在于桌面是在所有窗口的后面,我们完全可以是使我们自己的窗体具有这种性质。

    procedure TForm1.FormCreate(Sender: TObject);
    var
      hDeskTop:THandle;
    begin
      hDeskTop:=FindWindow('Progman', 'Program Manager');
      windows.SetParent(handle,hDeskTop);

    end;

    按照上面的代码试一试,看看win+D会不会让这个Form1窗体最小化到任务栏?答案当然是否定的,因为它已经具有了和桌面一样的属性。这就是这次教程的技巧之一。

    Sidebar应当靠在桌面的右边或者其他什么地方,这在Delphi里是十分简单的。在Object Inspector中设置Form1的BorderStyle为bsNone;Width为195;在FormCreate中加入如下:

    procedure TForm1.FormCreate(Sender: TObject);
    var
      hDeskTop:THandle;
      r: Trect;
    begin
      r:= Screen.DesktopRect;  //读取桌面分辨率
      Self.Top := 0;
      Self.Left := r.Right-r.Left-Self.Width ; //靠右侧
      Self.Height :=  r.Bottom-r.Top;          //与桌面等高

      hDeskTop:=FindWindow('Progman', 'Program Manager');
      windows.SetParent(handle,hDeskTop);

    end;

    就会建立一个靠右侧的Sidebar(退出时按Alt+F2),很好玩吧。这次就到这里,下次再见。

    展开全文
  • 在我们日常生活中,总会有一些零碎的需求,比如需要...软件启动后只会出现一个任务栏图标,然后使用【Alt+空格】便可以随时呼出uTools的主要功能界面,一个简单的输入框,那么它可以为我们做什么呢? 桌面快捷启动器 u

    在我们日常生活中,总会有一些零碎的需求,比如需要翻译一段文本,生成一个二维码,记一下备忘录以及将一段无法复制的文字识别复制下来等等,这些需求并不频繁,为此专门去下载对应的软件并不是我们最优的选择。
    uTools除了像其他工具箱一样将这些细微需求合并到一起,其插件化与即用即走的设计理念,一定可以为您带来另一种使用体验。

    一切都要从一个输入框说起

    软件启动后只会出现一个任务栏图标,然后使用【Alt+空格】便可以随时呼出uTools的主要功能界面,一个简单的输入框,那么它可以为我们做什么呢?
    在这里插入图片描述

    桌面快捷启动器

    uTools 最基础的功能是快捷启动器,支持英文、英文驼峰、中文拼音、拼音首字母来打开你的本地程序和系统设置。总之,只要你还记得一个大概的名字,基本都能找到,你拥有了它之后甚至可以将桌面的快捷图标全部删除,仅需要一个简单的提醒它一下就可以找到你所需要的软件及系统设置。

    在这里插入图片描述

    私人定制工具库

    除了快速启动程序外,uTools真正强大的地方是他丰富的插件体系,它拥有180+的官方与网友自行制作的插件并且还在持续丰富中,点击输入框界面右侧的图标便可以进入插件中心添加自己需要的插件定制升级自己的uTools了,下面简单介绍几个比较实用的插件。
    在这里插入图片描述

    一、本地搜索插件安装完成后会让你的搜索功能瞬间升级,基于Everything的本地文件快速查找功能可以让你快速找到不知被遗忘在哪个角落的文档,只需要你记得文件的一点点信息,并且查找速度要甩出电脑自带查找功能几十条街。
    在这里插入图片描述

    二、聚合翻译插件,可以多窗口多词典同时翻译交叉比对,与超级面板功能配合还可以做到随意复制,实时翻译。
    在这里插入图片描述

    三、备忘助手插件,备忘一切你觉得可能有用的文本信息,有需要时,搜索一下,粘贴一下,一切都变得简单。
    在这里插入图片描述

    四、OCR图片转文字插件,可以非常便捷的将我们截图下来的文字图片识别并复制下来,可应对一些文字无法复制的情况,截图软件有自带的用微信的也可以。

    在这里插入图片描述

    还有一种更便捷的方式

    除了这些uTools还有很多强大的功能,由于篇幅有限就由你自己去发掘吧,上述的这些功能除了呼出输入框再使用外还有一种更便捷的使用方式,那就是uTools的超级面板功能,超级面板可以根据当前所选内容提供相对应的处理菜单,只需要选中对应图片或文字点击鼠标中键便可以了。
    在这里插入图片描述

    一点小心得

    要退出插件页面的话只需要按一下ESC键就可以了,但是会有后台驻留现象,虽然每个插件占用内存都很小但是开启过多的话也会造成电脑卡顿,这里说两种处理方法。
    1.设置全局快捷键功能关键字输入“Clear”,这样可以使用快捷键直接使后台插件全部退出,也可以呼出uTools搜索框后输入“Clear”使用此功能。
    在这里插入图片描述

    2.可以将自己不需要后台驻留的插件设置为“隐藏插件后完全退出”,设置方法为呼出uTools输入框后输入插件名称打开对应的插件,点击图示的三个竖点后将当前插件选项设置为“隐藏插件后完全退出”。

    在这里插入图片描述

    软件获取

    链接容易失效,请在公众号后台回复:utools

    文章来自公众号:U9软件宝库

    展开全文
  • SystemUI属于系统级apk,位置在frameworks\base\packages\SystemUI,主要功能有: 状态栏信息显示,比如电池,wifi信号,3G/4G等icon显示 通知面板,比如系统消息,第三方应用消息 近期任务栏显示面板,比如...

    SystemUI概览

    SystemUI属于系统级的apk,位置在frameworks\base\packages\SystemUI,主要功能有:

    • 状态栏信息显示,比如电池,wifi信号,3G/4G等icon显示
    • 通知面板,比如系统消息,第三方应用消息
    • 近期任务栏显示面板,比如长按近期任务快捷键,显示近期使用的应用
    • 截图服务
    • 壁纸服务
    • ……

    SystemUI的启动流程

    SystemServer启动后,会在Main Thread启动ActivityManagerService,当ActivityManagerService systemReady后,会去启动SystemUIService。
    SystemServer路径:frameworks/base/services/java/com/android/server/SystemServer.java

    mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                ......
                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                ......
            }            
         });

    在这个方法里启动一个SystemUIService服务

    static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService"));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
    }

    通过startServiceAsUser,SystemUIService就启动了,即SystemUI进程开机启动。

    public class SystemUIService extends Service {
    
        @Override
        public void onCreate() {
            super.onCreate();
            ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        }
        ......

    在SystemUIService的onCreate方法中会调用SystemUIApplication的startServicesIfNeeded方法,这个方法会调用 startServicesIfNeeded(SERVICES)方法启动一系列服务(并不是真正的service,都继承自SystemUI)

    public class SystemUIApplication extends Application {
        ......
    
        /**
         * The classes of the stuff to start.
         */
        private final Class<?>[] SERVICES = new Class[] {
                com.android.systemui.tuner.TunerService.class,
                com.android.systemui.keyguard.KeyguardViewMediator.class,
                com.android.systemui.recents.Recents.class,
                com.android.systemui.volume.VolumeUI.class,
                Divider.class,
                com.android.systemui.statusbar.SystemBars.class,
                com.android.systemui.usb.StorageNotification.class,
                com.android.systemui.power.PowerUI.class,
                com.android.systemui.media.RingtonePlayer.class,
                com.android.systemui.keyboard.KeyboardUI.class,
                com.android.systemui.tv.pip.PipUI.class,
                com.android.systemui.shortcut.ShortcutKeyDispatcher.class,
                com.android.systemui.VendorServices.class
        };
    
        ......
    
        public void startServicesIfNeeded() {
            startServicesIfNeeded(SERVICES);
        }
    }

    所有SERVICES统一继承了SystemUI类:

    public abstract class SystemUI {
        ......
    
        public abstract void start();
    
        protected void onConfigurationChanged(Configuration newConfig) {
        }
    
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        }
    
        protected void onBootCompleted() {
        }
        
        ......
    }

    startServicesIfNeeded方法会遍历SERVICES 这个数组,依次调用service的start方法启动服务。

    private void startServicesIfNeeded(Class<?>[] services) {
        ......
    
        final int N = services.length;
        for (int i=0; i<N; i++) {
            Class<?> cl = services[i];
            if (DEBUG) Log.d(TAG, "loading: " + cl);
            try {
                Object newService = SystemUIFactory.getInstance().createInstance(cl);
                mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }
    
            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
    
            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
        ......
    }

    状态栏

    状态栏(SystemBars)service是SystemUI中最重要的service,代码量最多,最复杂的,界面结构也复杂。根据前面的内容可知,启动SystemBars是通过调用start()方法,如下图:

        public void start() {
            if (DEBUG) Log.d(TAG, "start");
            mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
                    mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
            mServiceMonitor.start();  // will call onNoService if no remote service is found
        }

    这里实质是回调到到SystemBars的onNoService()方法,最后是调用SystemBars的createStatusBarFromConfig()方法:

        private void createStatusBarFromConfig() {
            ......
            String clsName = mContext.getString(R.string.config_statusBarComponent);
            ......
            try {
                cls = mContext.getClassLoader().loadClass(clsName);
            } catch (Throwable t) {
                throw andLog("Error loading status bar component: " + clsName, t);
            }
            try {
                mStatusBar = (BaseStatusBar) cls.newInstance();
            } catch (Throwable t) {
                throw andLog("Error creating status bar component: " + clsName, t);
            }
            ......
            mStatusBar.start();
            ......
        }

    上图可以看到,从string资源文件里面读取class name,通过java的映射机制实例化对象,然后调用start()方法启动,class name的值如下图:

        <!-- Component to be used as the status bar service.  Must implement the IStatusBar
         interface.  This name is in the ComponentName flattened format (package/class)  -->
        <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>

    该配置文件在SystemUI/res/values/config.xml中。所以实质是PhoneStatusBar调用了start()方法。
    SystemBars模块的初始化过程主要涉及的类有:

    SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
    SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
    SystemUI/src/com/android/systemui/statusbar/CommandQueue.java

    PhoneStatusBar的父类是BaseStatusBar继承于SystemUI,SystemBars调用PhoneStatusBar中的start()方法,类关系图如下:

    PhoneStatusBar的start()

    public void start() {
            ......
            super.start(); // calls createAndAddWindows()
    
            ......
            addNavigationBar();
    
            ......
    }

    如上图,调用父类中的start()方法,即BaseStatsuBar中的start()方法。然后调用addNavigationBar()方法实例化导航条。状态栏的布局层次结构如下图:

    继续看BaseStatsuBar中的方法。

    public void start() {
        ......
    
        mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
    
        ......
    
        // Connect in to the status bar manager service
        mCommandQueue = new CommandQueue(this);
    
        int[] switches = new int[9];
        ArrayList<IBinder> binders = new ArrayList<IBinder>();
        ArrayList<String> iconSlots = new ArrayList<>();
        ArrayList<StatusBarIcon> icons = new ArrayList<>();
        Rect fullscreenStackBounds = new Rect();
        Rect dockedStackBounds = new Rect();
        try {
            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
                    fullscreenStackBounds, dockedStackBounds);
        } catch (RemoteException ex) {
            // If the system process isn't there we're doomed anyway.
        }
    
        createAndAddWindows();
    
        ......
    
        // Set up the initial icon state
        int N = iconSlots.size();
        int viewIndex = 0;
        for (int i=0; i < N; i++) {
            setIcon(iconSlots.get(i), icons.get(i));
        }
    
        // Set up the initial notification state.
        try {
            mNotificationListener.registerAsSystemService(mContext,
                    new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
                    UserHandle.USER_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to register notification listener", e);
        }
    
        ......
    }

    如上面BaseStatsuBar中的start()方法,实例化一些对象,此处的对象都是“空值”,然后通过IStatusBarService的实例mBarService对象注册到StatusBarManagerService。

    mCommandQueue是CommandQueue的实例,在StatusBarManagerService的远程回调,实现StatusBarManagerService和SystemUI的通信。

    然后调用createAndAddWindows()方法,该方法初始化status bar,notification,quick settings等的View控件。

    在这里,还需要注意NotificationListenerService的实例mNotificationListener的registerAsSystemService()方法,该方法主要实现StatusBarManagerService和SystemUI的notification的控制通道,也就是说,StatusBarManagerService收到notification变化时,通过此通道通知SystemUI显示notification的变化。

    通知显示过程

    一个APP需要显示notification首先需要实例化一个NotificationManager的对象,然后调用NotificationManager的方法notify()方法把创建好的Notification对象作为参数传进去。

    public void notify(int id, Notification notification){
        notify(null, id, notification);
    }
    public void notify(String tag, int id, Notification notification){
        notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
    }
    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user){
        ......
        INotificationManager service = getService();
        ......
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    copy, idOut, user.getIdentifier());
            ......
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    上图中可以看到一个service的对象调用了enqueueNotificationWithTag()方法,该方法实质是远程调用NotificationManagerService中的enqueueNotificationWithTag()方法,该方法又直接调用enqueueNotificationInternal(),该方法如下:

    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
            final int callingPid, final String tag, final int id, final Notification notification,
            int[] idOut, int incomingUserId) {
        ......
        final StatusBarNotification n = new StatusBarNotification(
                pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
                user);
    
        ......
    
        final NotificationRecord r = new NotificationRecord(getContext(), n);
        mHandler.post(new EnqueueNotificationRunnable(userId, r));
    
        ......
    }

    这里会把NotificationManager传递过来的Notification对象进行很多处理,比如变换成NotificationRecord,实质就是把Notification缓存下来。在上图的这个过程,还有一些其它的处理逻辑,在这里就不详细说明。最后把这个NotificationRecord传递给EnqueueNotificationRunnable线程来处理:

        private class EnqueueNotificationRunnable implements Runnable {
            private final NotificationRecord r;
            private final int userId;
    
            EnqueueNotificationRunnable(int userId, NotificationRecord r) {
                this.userId = userId;
                this.r = r;
            };
    
            @Override
            public void run() {
    
                synchronized (mNotificationList) {
                    final StatusBarNotification n = r.sbn;
                    ......
    
                    if (notification.getSmallIcon() != null) {
                        StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
                        mListeners.notifyPostedLocked(n, oldSbn);
                    } else {
                        ......
                    }
    
                    buzzBeepBlinkLocked(r);
                }
            }
        }

    代码的末尾调用了buzzBeepBlinkLocked()方法,该方法主要处理Notification的声音和震动的逻辑。mListeners调用了notifyPostedLocked()方法,此方法最终会执行到如下图的代码:

    private void notifyPosted(final ManagedServiceInfo info,
            final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
        final INotificationListener listener = (INotificationListener)info.service;
        StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
        try {
            listener.onNotificationPosted(sbnHolder, rankingUpdate);
        } catch (RemoteException ex) {
            Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
        }
    }

    info.service返回一个INotificationListener的实例对象,该对象在上文中的mNotificationListener.registerAsSystemService()方法进行设置,所以listener.onNotificationPosted()方法实质是远程回调SystemUI中的方法:

    private final NotificationListenerService mNotificationListener =
            new NotificationListenerService() {
        ......
    
        @Override
        public void onNotificationPosted(final StatusBarNotification sbn,
                final RankingMap rankingMap) {
            ......
            if (sbn != null) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        ......
    
                        if (isUpdate) {
                            updateNotification(sbn, rankingMap);
                        } else {
                            addNotification(sbn, rankingMap, null /* oldEntry */);
                        }
                    }
                });
            }
        }
    }

    代码运行又回到了BaseStatusBar.java类中,从APP调用NotificationManager的notify()方法到BaseStatusBar的addNotification()或updateNotification()方法,经历了一个复杂的过程。就不再往下详情说明Notification到达SystemUI的处理过程了,之后有机会我们继续分析。

    锁屏

    锁屏(Keyguard)service在SystemUI是一个比较特殊的模块,特殊在于SystemUI启动的service只是一个信息传递者,也就是KeyguardViewMediator,并没有做锁屏或解屏的实质操作。在这里,涉及到三个比较关键的类是:

    SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
    SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
    Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java

    KeyguardViewMediator和KeyguardService在源码中位于SystemUI中,而KeyguardUpdateMonitor则位于KeyGuard中。在KeyguardViewMediator的初始化中主要做了三件事,如图:

    public void start() {
        synchronized (this) {
            setupLocked();
        }
        putComponent(KeyguardViewMediator.class, this);
    }
    private void setupLocked() {
        ......
    
        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
    
        ......
    
        mStatusBarKeyguardViewManager =
                SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(mContext,
                        mViewMediatorCallback, mLockPatternUtils);
        final ContentResolver cr = mContext.getContentResolver();
    
        mDeviceInteractive = mPM.isInteractive();
    
        ......
    
        if (soundPath != null) {
            mLockSoundId = mLockSounds.load(soundPath, 1);
        }
        if (soundPath == null || mLockSoundId == 0) {
            Log.w(TAG, "failed to load lock sound from " + soundPath);
        }
        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
        if (soundPath != null) {
            mUnlockSoundId = mLockSounds.load(soundPath, 1);
        }
        if (soundPath == null || mUnlockSoundId == 0) {
            Log.w(TAG, "failed to load unlock sound from " + soundPath);
        }
        soundPath = Settings.Global.getString(cr, Settings.Global.TRUSTED_SOUND);
        if (soundPath != null) {
            mTrustedSoundId = mLockSounds.load(soundPath, 1);
        }
        if (soundPath == null || mTrustedSoundId == 0) {
            Log.w(TAG, "failed to load trusted sound from " + soundPath);
        }
    
        ......
    }

    实例化KeyguardUpdateMonitor的实例mUpdateMonitor,KeyguardUpdateMonitor负责更新已经锁屏界面上的内容(如时间)。当然,KeyguardUpdateMonitor只是一个信息传递者,实际去刷新界面的是StatusBar模块。Keyguard模块通知StatusBar刷新解密是通过KeyguardUpdateMonitorCallback这个类进行远程回调,该类的实例在StatusBar模块启动时通过KeyguardService获取到IKeyguardService的远端实例,通过IKeyguardService远程调用IKeyguardService的addStateMonitorCallback()方法实例化KeyguardUpdateMonitorCallback对象,SystemUI/src/com/android/systemui/keyguard/KeyguardService.java

    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
    
        @Override // Binder interface
        public void addStateMonitorCallback(IKeyguardStateCallback callback) {
            checkPermission();
            mKeyguardViewMediator.addStateMonitorCallback(callback);
        }
    
        ......
    
        @Override // Binder interface
        public void onScreenTurnedOn() {
            Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
            checkPermission();
            mKeyguardViewMediator.onScreenTurnedOn();
            Trace.endSection();
        }
    
        ......
    };

    SystemUI启动的Keyguard模块并没有真正的去操作锁屏界面,而是作为一个信息传递者把信息传递给StatusBar模块。
    KeyguardService在KeyguardServiceDelegate中绑定调用。
    frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java:

    public void bindService(Context context) {
        Intent intent = new Intent();
        final Resources resources = context.getApplicationContext().getResources();
    
        final ComponentName keyguardComponent = ComponentName.unflattenFromString(
                resources.getString(com.android.internal.R.string.config_keyguardComponent));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        intent.setComponent(keyguardComponent);
    
        boolean isBox = isBox();
    
        if (isBox || !context.bindServiceAsUser(intent, mKeyguardConnection,
                Context.BIND_AUTO_CREATE, mScrimHandler, UserHandle.SYSTEM)) {
            Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
            mKeyguardState.showing = false;
            mKeyguardState.showingAndNotOccluded = false;
            mKeyguardState.secure = false;
            synchronized (mKeyguardState) {
                // TODO: Fix synchronisation model in this class. The other state in this class
                // is at least self-healing but a race condition here can lead to the scrim being
                // stuck on keyguard-less devices.
                mKeyguardState.deviceHasKeyguard = false;
                hideScrim();
            }
        } else {
            if (DEBUG) Log.v(TAG, "*** Keyguard started");
        }
    }
    
    private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
            mKeyguardService = new KeyguardServiceWrapper(mContext,
                    IKeyguardService.Stub.asInterface(service), mShowingStateChangedCallback);
            if (mKeyguardState.systemIsReady) {
                // If the system is ready, it means keyguard crashed and restarted.
                mKeyguardService.onSystemReady();
                if (mKeyguardState.currentUser != UserHandle.USER_NULL) {
                    // There has been a user switch earlier
                    mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
                }
                // This is used to hide the scrim once keyguard displays.
                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
                    mKeyguardService.onStartedWakingUp();
                }
                if (mKeyguardState.screenState == SCREEN_STATE_ON
                        || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
                    mKeyguardService.onScreenTurningOn(
                            new KeyguardShowDelegate(mDrawnListenerWhenConnect));
                }
                if (mKeyguardState.screenState == SCREEN_STATE_ON) {
                    mKeyguardService.onScreenTurnedOn();
                }
                mDrawnListenerWhenConnect = null;
            }
            if (mKeyguardState.bootCompleted) {
                mKeyguardService.onBootCompleted();
            }
            if (mKeyguardState.occluded) {
                mKeyguardService.setOccluded(mKeyguardState.occluded, false /* animate */);
            }
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
            mKeyguardService = null;
        }
    
    };

    com.android.internal.R.string.config_keyguardComponent的默认配置值:

    <!-- Keyguard component -->
    <string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>

    KeyguardViewMediator启动的流程图如下:

    总结

    先大概看一遍流程,这个apk比较复杂,之后还会分析。

    展开全文
  • 主要包括微信在主界面新增了小程序任务栏的功能 小程序菜单进行了升级,并提供小程序间快速切换的功能 开放了小游戏开发文档和开发者工具 小程序支持新类目——小游戏如何体验微信小游戏打开微信—>在搜索栏中输入...
  • Traffic Monitor一款用于Windows平台网速监控悬浮窗软件,可以显示当前网速、CPU及内存利用率,支持嵌入到任务栏显示,支持更换皮肤、历史流量统计等功能。 相关链接: 请点击此处下载TrafficMonitor最新...
  • 界面组成:1、屏幕顶端的应用程序(类似... 任务栏的最右边是工作区切换按钮。 问题:如何在centos桌面环境进入“命令提示行”界面?如何查命令的功能简介?centos系统的重启、关机命令是什么?方法:在桌面空白处点...
  • Autoware的功能主要适合于城市,但也可以涵盖高速公路,高速公路,中山地区和地理围栏地区。 Autoware代码库受Apache 2许可证保护。 请自行决定使用它。 为了安全使用,我们为不拥有真正自动驾驶汽车人提供了...
  • 本程序主要功能是设置word查找和替换的功能程序分为两大块查找功能和替换功能特别说明:电脑上如果有360杀毒软件,第一次使用前请关闭右下角任务栏的360杀毒和360安全卫士,否则它会阻止程序的运行.有关为什么会阻止...
  • 针式PKM的主要技术指标: 知识库支持文档数:>3万个文档,类型包括:Word、PDF、PPT、图片、安装文件、压缩文件等 搜索支持:文件名瞬间搜索、Word\PDF等文档内容的全文快速搜索 归类方法:分类、标签、多个文档关联...
  • 本程序主要功能是设置word表格的功能特别说明:电脑上如果有360杀毒软件,第一次使用前请关闭右下角任务栏的360杀毒和360安全卫士,否则它会阻止程序的运行.有关为什么会阻止程序运行的贴子:...
  • 6.这时软件自动添加基本头文件,因为这个程序我们不需要其他的功能,所以 直接点击Next。 7.我们将base class 选为QDialog 对话框类。然后点击Next。 8.点击Finish,完成工程建立。 9.我们可以看见工程中所有...
  • 昨天做了什么: ...除了主要功能之外:最主要问题美观,使用者体验感很差。 遇到问题: 不知道大体上app格调要成什么样子,具体到很细标题,不同字体颜色背景等等。 转载于:https://www.c...
  • Program of taskbar & hotkey

    2005-02-05 17:08:00
    打算分两次写成一个列于桌面右侧sidebar(中文名不知道叫什么,好像应该算是任务栏,因为主要灵感来自于Desktop Sidebar)程序,可以从网上读取天气预报,可以显示当前时钟等基本功能(你可以加入自己的功能)。...
  •  forward服务器请求资源,服务器直接访问目标地址URL,把那个URL响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送内容从哪儿来,所以它地址中还是原来地址。...
  • excel使用

    2012-11-25 17:06:01
    自定义函数,也叫用户定义函数,Excel最富有创意和吸引力的功能之一,下面我们在Visual Basic模块中创建一个函数。 在下面例子中,我们要给每个人金额乘一个系数,如果上班时工作餐,就打六折;如果加班...
  •  网络应用程序可在没有网址列(Omnibox)和浏览工具栏的情况下在Chrome中执行。 [编辑本段]其他  工作管理员(Task Manager)  利于管理各个分页与外挂,有助用户终止恶意操作。 [编辑本段]浏览器标准测试  ●...
  • 随着H5游戏一个个潮起潮落,今天小编再次为大家带来一款非常有趣H5游戏微信小游戏IU同学,玩家可以在微信直接开始这款游戏,不过这款游戏并不是什么需要操作游戏,主要功能就是促进同学之间互动,不管在校...
  • 如果由其他线程完成工作都后台任务,那么应该降低它们优先级,从而提高前台程序响应性。 活锁 要解决这种活锁问题,需要在重试机制中引入随机性(randomness)。为了避免这种情况发生,需要让...
  • 同时,迷你搜索框常驻任务栏,一呼即搜;本机文档、图片、程序、视频智能分类,更易查找 光速搜索为什么快 据悉,光速搜索主要利用了NTFS文件系统特性,可以根据文件名查找更快。这种方式利用了系统自身功能...
  • 不能访问主要是由于XP默认不开启guest,而且即使开了guest,XP默认不允许guest从网络访问计算机。还有就是那个值得注意问题。相信一些不考虑安全地方或是电脑公司给人做系统密码都,但这样不允许...
  • 它们各自的功能是什么? 答:膾入处理扫描序:识别并接受从外部输入处理谤求和其它有关信息。 内部处理号码分析序:根据输入信号和现有状态进行分析、识别,然后决 定下一步任务。 内部处理路山选择私序:根据...
  • 如何制作类似Windows任务栏的窗口 第5章 SDI和MDI窗口 文档、视图、框架窗口间的关系和消息传送规律怎样的 如何切分窗口 如何固定视图间的分隔线 如何动态改变切分窗口的大小 如何实现切分窗口中视图的动态切换 ...
  • 在xp下,无法切换用户。

    千次阅读 2007-05-10 13:49:00
    在 Windows XP系统下,单击”开始”菜单-...启用方法为:在任务栏上依次单击”开始控制面板用户帐户更改用户 登录或注销方式”,然后勾选”使用欢迎屏幕”和”使用用户快速切换”,最后单击”确定”按钮即可
  • 4)想要设置什么具体功能,可以直接百度或者直接在设置里搜索 ##【简单介绍】 1. 对比 windows mac 我电脑 finder访达 应用 启动台 c盘、d盘 没有盘,自己分文件夹 控制面板 设置 任务管理器 活动监视器 开始 顶...
  • 第十三章,讨论MFC工具栏和状态栏的设计及其实现,分析MFC如何以CControlBar为基础,派生出CStatusBar、CToolBar、CDialogBar等子类,实现MFC工具栏和状态栏标准处理。 第十四章,讨论MFC的Socket类。 第一章到...
  • 4.C#中委托是什么?事件是不是一种委托? 答 : 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数引用。 是,是一种特殊委托 5.override与重载区别 答 : override 与重载...
  • 从真正意义上解决与避免“我该看什么”,“我想看什么普遍用户困扰,它将为您量身定制与您生活息息相关伙伴。本站提供迅雷看看播放器官方下载。 迅雷看看播放器问题专区:...
  • 在这一讲中,我们主要是了解一下 Linux 概况,以及对 Linux 有一个初步感性认识。 一.什么是Linux? Linux 一个以 Intel 系列 CPU(CYRIX,AMD CPU也可以)为硬件平台,完全免费 UNIX 兼容系统,完全...
  • PROJECT 2007宝典 9/9

    2012-04-01 19:13:00
    从设置预算到分配资源,再到跟踪结果,本书的7个部分按照逻辑顺序详细地介绍了项目管理中的主要元素,您可以从中找到所需的内容。  识别项目的目标和范围;  在企业内和多个位置管理项目;  从甘特图和视图中获得...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

任务栏的主要功能是什么