How Android OS process the SoftKeyboard?

How to capture the stacktrace of Android OS specifically for the SoftKeyboard implementation?

First create an application based on the SoftKeyboard sample, and then “Run” it – it will start the AVD emulator if necessary, and install itself as an apk into the started AVD emulator. The output in the console (Windows->ShowView->Console) view is shown below:

[2011-01-10 08:47:40 – my2.1proj_softkey] New emulator found: emulator-5554
[2011-01-10 08:47:40 – my2.1proj_softkey] Waiting for HOME (‘android.process.acore’) to be launched…
[2011-01-10 08:48:12 – my2.1proj_softkey] WARNING: Application does not specify an API level requirement!
[2011-01-10 08:48:12 – my2.1proj_softkey] Device API version is 7 (Android 2.1-update1)
[2011-01-10 08:48:12 – my2.1proj_softkey] HOME is up on device ’emulator-5554′
[2011-01-10 08:48:12 – my2.1proj_softkey] Uploading my2.1proj_softkey.apk onto device ’emulator-5554′
[2011-01-10 08:48:13 – my2.1proj_softkey] Installing my2.1proj_softkey.apk…
[2011-01-10 08:48:34 – my2.1proj_softkey] Success!
[2011-01-10 08:48:34 – my2.1proj_softkey] /my2.1proj_softkey/bin/my2.1proj_softkey.apk installed on device

The last line indicated that the application is now running. Use the keyboard setting and select that as the standard keyinput. Since the task is now running – identify the name under the “Devices” (Windows->ShowView->Devices) view. Then look out for the green “beetle” button, left click on the task, and then click the “green beetle” to enable the task for debugging. (Eclipse will indicate that only applications with source codes available are possible to be debugged).

Then open up the “Outline” view, where all the methods are shown (Windows->ShowView->Other and inside the “filter text” window, enter “Outline”), right click on the method to set breakpoint on and select “Toggle Method Breakpoint” to enable breakpointing on the method.

Next select “Run” on the application, and after compilation Eclipse will attempt to reinstall (click Windows->ShowView->Console):

[2011-01-10 09:10:55 – my2.1proj_softkey] Android Launch!
[2011-01-10 09:10:55 – my2.1proj_softkey] adb is running normally.
[2011-01-10 09:10:55 – my2.1proj_softkey] No Launcher activity found!
[2011-01-10 09:10:55 – my2.1proj_softkey] The launch will only sync the application package on the device!
[2011-01-10 09:10:55 – my2.1proj_softkey] Performing sync
[2011-01-10 09:10:55 – my2.1proj_softkey] Automatic Target Mode: using existing emulator ’emulator-5554′ running compatible AVD ‘my2.1avd’
[2011-01-10 09:10:55 – my2.1proj_softkey] WARNING: Application does not specify an API level requirement!
[2011-01-10 09:10:55 – my2.1proj_softkey] Device API version is 7 (Android 2.1-update1)
[2011-01-10 09:10:58 – my2.1proj_softkey] Application already deployed. No need to reinstall.
[2011-01-10 09:10:58 – my2.1proj_softkey] /my2.1proj_softkey/bin/my2.1proj_softkey.apk installed on device
[2011-01-10 09:10:58 – my2.1proj_softkey] Done!

Subsequent clicking on the softkeyboard will immediately trigger the following Using DDMS and Eclipse to capture the stacktrace in Android emulation the following stacktrace was generated (click Windows->ShowView->Debug):

DalvikVM[localhost:8615]
Thread [<3> main] (Suspended (entry into method onKeyDown in SoftKeyboard))
SoftKeyboard.onKeyDown(int, KeyEvent) line: 338
KeyEvent.dispatch(KeyEvent$Callback, KeyEvent$DispatcherState, Object) line: 1037
InputMethodService$InputMethodSessionImpl(AbstractInputMethodService$AbstractInputMethodSessionImpl).dispatchKeyEvent(int, KeyEvent, InputMethodSession$EventCallback) line: 135
IInputMethodSessionWrapper.executeMessage(Message) line: 76
HandlerCaller$MyHandler.handleMessage(Message) line: 45
HandlerCaller$MyHandler(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4363
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object…) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 860
ZygoteInit.main(String[]) line: 618
NativeStart.main(String[]) line: not available [native
method]
Thread [<13> Binder Thread #2] (Running)
Thread [<11> Binder Thread #1] (Running)

First, shown below is the SoftKeyboard class’s onKeyDown() method (from Android SDK sample for SoftKeyboard) implementation:

/**
* Use this to monitor key events being delivered to the application.
* We get first crack at them, and can either resume them or let them
* continue to the app.
*/
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
// The InputMethodService already takes care of the back
// key for us, to dismiss the input method if it is shown.
// However, our keyboard could be showing a pop-up window
// that back should dismiss, so we first allow it to do that.
if (event.getRepeatCount() == 0 && mInputView != null) {
if (mInputView.handleBack()) {
return true;
}
}
break;

case KeyEvent.KEYCODE_DEL:
// Special handling of the delete key: if we currently are
// composing text for the user, we want to modify that instead
// of let the application to the delete itself.
if (mComposing.length() > 0) {
onKey(Keyboard.KEYCODE_DELETE, null);
return true;
}
break;

case KeyEvent.KEYCODE_ENTER:
// Let the underlying text editor always handle these.
return false;

 

default:
// For all other keys, if we want to do transformations on
// text being entered with a hard keyboard, we need to process
// it and do the appropriate action.
if (PROCESS_HARD_KEYS) {
if (keyCode == KeyEvent.KEYCODE_SPACE
&& (event.getMetaState()&KeyEvent.META_ALT_ON) != 0) {
// A silly example: in our input method, Alt+Space
// is a shortcut for ‘android’ in lower case.
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
// First, tell the editor that it is no longer in the
// shift state, since we are consuming this.
ic.clearMetaKeyStates(KeyEvent.META_ALT_ON);
keyDownUp(KeyEvent.KEYCODE_A);
keyDownUp(KeyEvent.KEYCODE_N);
keyDownUp(KeyEvent.KEYCODE_D);
keyDownUp(KeyEvent.KEYCODE_R);
keyDownUp(KeyEvent.KEYCODE_O);
keyDownUp(KeyEvent.KEYCODE_I);
keyDownUp(KeyEvent.KEYCODE_D);
// And we consume this event.
return true;
}
}

And looking up the code “frameworks/base/core/java/android/app/ActivityThread.java” line 4630 of 4639:

public static final void main(String[] args) {
SamplingProfilerIntegration.start();

Process.setArgV0(“<pre-initialized>”);

Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();
thread.attach(false);

Looper.loop();

if (Process.supportsProcesses()) {
throw new RuntimeException(“Main thread loop unexpectedly exited”);

 

From above, we can deduced that Looper.loop()’s being executed, thus leading to the stack trace as shown above.

Notice also that the line number for Looper.loop() is higher in the current source code (from recent’s “repo sync” update) as compared with the emulator which is using Android 2.1 Update version.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: