|

|
from http://ysl-paradise.blogspot.com/2008/12/blog-post.html
Handle the open/close keyboard usage for your Android applications
之前写了一个 Android 版的世界时钟 (world clock) 程式,自认为应该没什麽大问题了,就丢上网让使用者开始下载。嗯,下载数是不少,心喜之余,还是有几个人反应,无法完成注册的问题。
由於,当时 G1 手机没有到手,只能用模拟机测,测了半天,一直无法重现使用者提到的问题。只好再检视注册相关的程式码,一样,看了不下十遍,还是没看到什麽问题。终於,有天想到使用者要注册时,应该要输入使用者名称及注册码,而实机不像我们在模拟机上,直接用 PC 的键盘输入,他应该要打开键盘输入才行。会不会,是这个问题的关系?
首先,第一个是做的是,要如何在模拟机上,模拟打开键盘这个动作?告诉你,你在网路上一定找不到这样的资讯。今天就分享给你,这可是我尝试了许久,才发现的秘诀。
告诉你,答案就是按下 PC 键盘上的 KEYPAD_7 or KEYPAD_9 键。疑,这不就是 如何以程式的方式,旋转 Android 萤幕 文章中,提到的旋转模拟机萤幕方向 (直立 水平) 的按键吗?的确是,所有的文件都只说明,这是用来旋转萤幕的按键,根本没人提到,这也是模拟键盘打开或关闭的按键。
还来我才知道,在实机上,系统并不会自动随着机器的旋转,而自动旋转萤幕方向。只有当你打开键盘时,系统才会自动将萤幕转成水平。当你收起键盘时,才又将萤幕转成垂直方向。
那这开启或关闭键盘 (正确地,应该说旋转萤幕方向) 的动作,为什麽会造成程式的问题呢?
原来,这萤幕的旋转,是靠重新起动你的 activity (不是整个应用程式喔) 而达成的。虾米,这是什麽意思?我发现,当萤幕准备要开始旋转时,系统会先杀掉你现在的 activity,接着呼叫底层的显示系统,旋转萤幕的方向,最後才又重新启动你的 activity。从使用者看来,只是萤幕转个方向而已,什麽事也没发生。但从程式面来看,这可是已经经历过一次生死轮回了。
我写个简单的程式,证明给你看。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class activity_lift_cycle extends Activity {
public void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("", "onCreate(" savedInstanceState ")");
}
protected void
onRestart() {
super.onRestart();
Log.d("", "onRestart()");
}
protected void
onStart() {
super.onStart();
Log.d("", "onStart()");
}
protected void
onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d("", "onRestoreInstanceState()");
}
protected void
onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Log.d("", "onPostCreate()");
}
protected void
onResume() {
super.onResume();
Log.d("", "onResume()");
}
protected void
onPostResume() {
super.onPostResume();
Log.d("", "onPostResume()");
}
protected void
onSaveInstanceState(Bundle outState) {
outState.putInt("key", 123);
super.onSaveInstanceState(outState);
Log.d("", "onSaveInstanceState()");
}
protected void
onPause() {
super.onPause();
Log.d("", "onPause()");
}
protected void
onStop() {
super.onStop();
Log.d("", "onStop()");
}
protected void
onDestroy() {
super.onDestroy();
Log.d("", "onDestroy()");
}
protected void
onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("", "onNewIntent()");
}
}
首先,当你执行这个程式後,你会看到底下这样的结果。
onCreate(null)
onStart()
onPostCreate()
onResume()
onPostResume()
可是当你按下 KEYPAD_7 ,将萤幕转成水平的方向,你会看到底下这样的结果。
onSaveInstanceState()
onPause()
onStop()
onDestroy()
onCreate(Bundle[{android:viewHierarchyState=
Bundle[{android:views=
android.util.SparseArray@43370a48}], key=123}])
onStart()
onRestoreInstanceState()
onPostCreate()
onResume()
onPostResume()
看到了吗? onDestroy() 证明系统杀了你的 activity, onCreate() 则是又重新启动你的 activity。
我原先无法让使用者无法完成注册的问题,就是有些 local variables 的值,因为这重起 activity 的动作,而不见了。
这个经验,让我学到了,千万要有程式随时会被系统杀掉的准备。
有经验的你,可能会发现为什麽 activity 上 EditText 内的文字,不会随着旋转萤幕的动作,而重设。翻翻 EditText 的原始码,你会发现其实 EditText 也有特别针对这样的行为来处理。所以说,如果你有写自己的 custom widget 时,别忘了也要做类似的处理。不过, widget 的处理动作,和 activity 完全不同。有机会的话,再谈这部份。
後记,在写这篇时,又去 Google 了 一下,看到 Rotational Forces…On Your Android App 中,也有详细提到关於旋转萤幕的问题处理。值得参考。
|
|