JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java ME、Google Android 平台與 JavaCard 討論區 » Android  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
己加入精華區
by koji at 2009-02-01 01:11
本主題所含的標籤
作者 [轉錄]記得要在程式中,處理鍵盤開啟或關閉的動作 [精華]
koji

秒速5センチメートル

站長

發文: 8415
積分: 19
於 2009-01-06 02:04 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
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 中,也有詳細提到關於旋轉螢幕的問題處理。值得參考。


reply to postreply to post
JCConf Taiwan 2015 開始售票了!!
Facebook上的TWJUG社團,歡迎加入
作者 Re:[轉錄]記得要在程式中,處理鍵盤開啟或關閉的動作 [Re:koji]
koji

秒速5センチメートル

站長

發文: 8415
積分: 19
於 2009-02-06 10:36 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
最近要固定螢幕
發現如果只有設定
android:screenOrientation="portrait"
雖然會固定,但是仍會呼叫onDestroy,onCreate...這樣

得加上
android:configChanges="orientation|keyboardHidden"
才不會重新來..0rz..

koji


reply to postreply to post
JCConf Taiwan 2015 開始售票了!!
Facebook上的TWJUG社團,歡迎加入
» JWorld@TW »  Java ME、Google Android 平台與 JavaCard 討論區 » Android

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8