編輯:關於Android編程
一、Power、Home、Menu、back以及Vol+、Vol-的處理
我們知道,在WindowManagerService創建的時候會聲明一個InputManager的實例,這個InputManager又會通過NativeInit實現將mCallbacks、looper等添加到C++中實現創建InputDispatcher和InputReader。然後將這兩個實例各加入到InputDispatcherThread和InputReaderThread之中,實現讀取輸入事件並且進行派發。
1、InputManager.java:
構造函數中有如下實現:
this.mCallbacks = new Callbacks();
這個很關鍵,它就是在C++層實現回調的方法。然後通過NativeInit添加到C++中去了。
private final class Callbacks {
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean
isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
event, policyFlags, isScreenOn);
}
public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
return mWindowManagerService.mInputMonitor.
interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
}
……
}
這些都是通過WindowManagerService調用mPolicy的實現具體功能的函數
2、com_android_server_InputManager.cpp
在android_server_InputManager_nativeInit函數中又有如下操作:
gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
這裡又將InputManager.java中實現的callbacks放到了NativeInputManager中的mCallbacksObj了。
同時構建InputManager:mInputManager = new InputManager(eventHub, this, this);
3、InputManager.cpp
在構造函數中有:
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
再由
class NativeInputManager : public virtual RefBase,
public virtual InputReaderPolicyInterface,
public virtual InputDispatcherPolicyInterface,
public virtual PointerControllerPolicyInterface {
}我們可以知道,InputManager的構造函數的第二個參數實際上就是InputDispatcherPolicyInterface的實現,也就是com_android_server_InputManager的實例。
由InputDispatcher的聲明我們知道,這裡policy自然就是com_android_server_InputManager了
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
mPolicy(policy),
mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(NULL),
mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
mCurrentInputTargetsValid(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE)
在InputReader讀取事件之後會喚醒InputDiapatcher函數,之後就開始調用InputDispatcher::notifyKey。詳細分析參見:
http://blog.csdn.net/luoshengyang/article/details/6882903
4、InputDispatcher.cpp
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
……
//這裡的mPolicy是InputManager
mPolicy->interceptKeyBeforeQueueing(&event, policyFlags);
……
}
5、回到com_android_server_InputManager:
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
uint32_t& policyFlags) {
if ((policyFlags & POLICY_FLAG_TRUSTED)) {
if (keyEventObj) {
//這裡,我們清晰地看到,mCallbacksObj是InputManager.java中的Callbacks了
//也就是調用它的interceptKeyBeforeQueueing了
wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
keyEventObj, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
}
android_view_KeyEvent_recycle(env, keyEventObj);
env->DeleteLocalRef(keyEventObj);
}
}
}
我們回到步驟1的Callbacks定義:
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean
isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
event, policyFlags, isScreenOn);
}
InputMonitor.java
public int interceptKeyBeforeQueueing(
KeyEvent event, int policyFlags, boolean isScreenOn) {
return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
}
這裡mService是WindowManagerService,mPolicy 則是如下定義(WindowManagerService中)
final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
PolicyManager.java
public static WindowManagerPolicy makeNewWindowManager() {
//sPolicy就是Policy的實例化
return sPolicy.makeNewWindowManager();
}
Policy.java
public WindowManagerPolicy makeNewWindowManager() {
return new PhoneWindowManager();
}
至此,正式調用PhoneWindowManager的實例。
因此處理hardkey的相關代碼是在PhoneWindowManager中了
作者:kakaBack概述:之前我聽到過一則新聞,就是說Ipone中的AssistiveTouch的設計初衷是給殘疾人使用的。而這一功能在亞洲(中國)的使用最為頻繁。雖不知道這新聞的可靠性,但
當下很多手機應用都會有一個非常類似的功能,即屏幕的下方顯示一行Tab標簽選項,點擊不同的標簽就可以切換到不同的界面,如以下幾個應用所示:以上底部這四個標簽,每一個分別對應
在微信小程序開發時,經常要用到一個控件會根據不同的情況和環境動態顯示與隱藏這種情況,下面就來實踐一把!上效果先它的實現方法有兩種,第一種方法:單選法,就是隱藏與顯示根據條
前言 Note: 本文中的策略適用於Android平台上android.location包中的定位API。不同於Google Location Services API,