android4.1 HOME键长按问题

    调试中发现,同一软件在密度不同的时候竟有不同的表现。当密度为120时,长按home键会弹出搜索条,并且手指不放开,搜索条保持显示;而当密度为160时,长按home键会先弹出搜索条,然后搜索条消失,显示最近程序。使用工具发现搜索条的id为search_panel_container,找到这处地方SearchPanelView.java中

protected void onFinishInflate() {
        super.onFinishInflate();
        mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mSearchTargetsContainer = findViewById(R.id.search_panel_container);
...

搜索条隐藏显示地方

public void show(final boolean show, boolean animate) {
        if (!show) {
            final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null;
            ((ViewGroup) mSearchTargetsContainer).setLayoutTransition(transitioner);
        }
...

定位这处代码,追踪发现是在BaseStatusBar.java中调用的

@Override
    public void hideSearchPanel() {
        int msg = MSG_CLOSE_SEARCH_PANEL;
        mHandler.removeMessages(msg);
        mHandler.sendEmptyMessage(msg);
    }
此处代码上方正好是

@Override
    public void showSearchPanel() {
        int msg = MSG_OPEN_SEARCH_PANEL;
        mHandler.removeMessages(msg);
        mHandler.sendEmptyMessage(msg);
    }

猜测这是显示调用搜索条的地方,定位追踪,发现果然会跳转到这段代码,再往上发现它的调用顺序为TabletStatusBar.java(3-2-1)

1、

@Override
    public void showSearchPanel() {
        super.showSearchPanel();
        WindowManager.LayoutParams lp =
            (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
        lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
    }
2、
 private Runnable mShowSearchPanel = new Runnable() {
        public void run() {
            showSearchPanel();
        }
    };
3、
private View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) {
                        mHandler.removeCallbacks(mShowSearchPanel);
                        mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
                    }
                break;

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mHandler.removeCallbacks(mShowSearchPanel);
                break;
            }
            return false;
        }
    };
至此,搜索条的显示搞清了,是由home键的监听器产生的。而最近程序的显示没有头绪,试着在BaseStatusBar.java中的
@Override
    public void toggleRecentApps() {
        int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
            ? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
        mHandler.removeMessages(msg);
        mHandler.sendEmptyMessage(msg);
    }
设置断点,代码会跳转到这边,发现是调用这段代码,一路追踪,在PhoneWindowManager.java中找到它的调用出处

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
if (keyCode == KeyEvent.KEYCODE_HOME) {
...
if (down) {
                if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                    try {
                        IStatusBarService statusbar = getStatusBarService();
                        if (statusbar != null) {
                            statusbar.preloadRecentApps();
                        }
                    } catch (RemoteException e) {
                        Slog.e(TAG, "RemoteException when preloading recent apps", e);
                        // re-acquire status bar service next time it is needed.
                        mStatusBarService = null;
                    }
                }
                if (repeatCount == 0) {
                    mHomePressed = true;
                } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                    if (!keyguardOn) {
                        handleLongPressOnHome();
                    }
                }
            }
到这步,真相大白,是通过mLongPressOnHomeBehavior的值去判断是否显示最近程序条,而mLongPressOnHomeBehavior是在handleLongPressOnHome中初始化的

private void handleLongPressOnHome() {
        // We can't initialize this in init() since the configuration hasn't been loaded yet.
        if (mLongPressOnHomeBehavior < 0) {
            mLongPressOnHomeBehavior
                    = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
            if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
                    mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
            }
        }

        if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
            performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);

            // Eat the longpress so it won't dismiss the recent apps dialog when
            // the user lets go of the home key
            mHomeLongPressed = true;
        }

        if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
            showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
            try {
                IStatusBarService statusbar = getStatusBarService();
                if (statusbar != null) {
                    statusbar.toggleRecentApps();
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "RemoteException when showing recent apps", e);
                // re-acquire status bar service next time it is needed.
                mStatusBarService = null;
            }
        }
    }
可以清楚的知道,mLongPressOnHomeBehavior的值是由config_longPressOnHomeBehavior设置的,而这个值是可配置的,在config.xml中可以找到

<!-- Control the behavior when the user long presses the home button.
            0 - Nothing
            1 - Recent apps dialog
            2 - Recent apps view in SystemUI
         This needs to match the constants in
         policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
    -->
    <integer name="config_longPressOnHomeBehavior">2</integer>
默认设置为2,所以会显示最近程序条。而在密度为120时,不显示的原因是因为values-sw600dp中的config.xml中这个默认值不同,为

<!-- see comment in values/config.xml -->
    <integer name="config_longPressOnHomeBehavior">0</integer>






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值