1、用(SDK starter package)的installler安裝Android SDK時提示無法找到JDK,但實際上機器上已經安裝了JDK。
一個對不少人有效解決方案是看到此提示時先點一下“回退”按鈕,再點“下一步”,就會發現JDK被找到了。參考連結
但在我機器上這個方法不起作用。所以我選擇不使用installer,而是下載zip格式的檔案,解壓縮後運行SDK Manager.exe即可。參考連結
2、在Eclipse裡建立一個Android項目,運行/調試時提示“Could not find xxx.apk!”
網上提到的大部分解決方案是clean整個項目,或選fix project properties功能表項目。但對我的環境不起作用。
升級到Eclipse 3.7後,新建立的android項目在Build階段報告一個異常“sun/security/x509/X500Name”,懷疑與所用的jdk(IBM JDK6)有關。果然,卸載IBM JDK並安裝SUN JDK後問題解決。
3、讓程式適應不同的螢幕解析度
可參考這個連結:Android螢幕解析度問題。
4、在android模擬器裡用10.0.2.2可訪問宿主機。
5、在setWidth()方法裡指定的寬度是以pixel為單位的,如何轉換為使用dip(device independent pixels)為單位?
使用下面的代碼,參考連結
// Converts 14 dip into its equivalent px
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, r.getDisplayMetrics());
6、彈出式對話方塊的用法,這個連結介紹得比較詳細。
7、匯出apk檔案時需要簽名,這個連結比較詳細。
8、android介面設計原則,參考這個連結。
9、使用merge(而不是layout)可以達到在避免重複寫layout的同時減少layout的數量。
10、真機USB調試比用AVD調試快得多,設定也很簡單,見這個連結。不過10.0.2.2不能用了,真機可以通過wifi訪問區域網路內的伺服器。
11、android-ui-utils,一個不錯的線上Android表徵圖產生器,地址在此。
12、調試時如果出現莫名其妙的null 指標錯誤,例如findViewByID()返回null,先試試clean一下整個project,通常都能解決。
13、讓ListView裡無資料時顯示一行資訊。
參考連結,注意ListView和TextView的id。
14、用自己的表徵圖替換ListView裡的RadioButton
在用作row的layout裡添加一個圖片,在java code裡覆蓋adapter的getView()方法,根據ListView的getCheckedItemPosition()結果設定圖片的可見度。注意不要通過setOnClickListener()方法設定view裡的圖片可見度,因為ListView只維護可見的那些row控制項,這樣做會導致很奇怪的結果(點第一條記錄結果第二條記錄被選中,並且滾動ListView時選中狀態還會隨機變化,見此連結)。
另外一個辦法是通過style設定checkMark為所需要的表徵圖,可能是更簡單的解決方案(還沒試)。
Update: 以上結果基於對ListView實現不瞭解的情況,其實使用RadioButton是可以實現的,見#22。
15、ListView的selection和choice是完全不同的,所以不要指望ListView#clearChoice()能清楚你已經是checked狀態的那些item。
16、螢幕方向變化時(橫屏->豎屏,或反過來),ListView裡發生變化的內容丟失,狀態回到開始時的樣子。
當螢幕方向發生變化時,android會重建整個Activity以便你構造更適合某個方向的UI。為了避免這種情況,在AndroidManifest.xml裡的那個Activity聲明上增加android:configChanges="orientation" 即可。詳見參考連結。
17、各手機平台模擬器/模擬器的下載連結。
18、AlertDialog#show()方法是不會阻塞當前線程的。
19、讓不同Activity之間進行通訊,例如一個TabActivity裡有多個Activity,它們之間需要傳遞一些訊息。
可使用BroadcastReceiver機制。 參考連結。要注意的是,tab還未啟動時是無法接收到訊息的,所以要在tabhost所在的activity裡也接收訊息,當tab啟動時傳給它。
20、Android SDK裡的style和theme文檔
見此連結。
21、Tab的樣式。
Android的tab樣式問題比較多,不同版本的樣式也不一樣。這裡有一個自訂樣式的參考連結。
22、在ListView裡使用單選/複選按鈕。
問題很多,這個連結看起來解決了問題,但在我的環境裡沒實驗成功。
Update: 以複選按鈕為例,本質的問題在於ListView裡的複選按鈕不知道對應的model是哪個,需要事先用CheckBox#setTag(myModelObject)關聯,onclick事件裡用getTag()改變其選中狀態。建議看這篇文檔。
23、strings.xml裡定義的字串裡增加參數。
在字串裡用“%1$s”、“%2$d”表示參數的序號和類型,然後用String.format()方法賦值。參考這個連結。
24、嵌入條碼/二維碼掃描功能
使用zxing。方法是在手機上先安裝BarcodeScanner.apk,然後在程式裡調用其提供的Activity,該Activity會返回掃描結果。 參考連結
25、改變ListView裡每個Row的背景顏色
直接在getView()裡寫view.setBackgroundColor()是不行的。正確的方法是先在drawable目錄裡建一個xml檔案,自己起名如my_row.xml,內容如下(關鍵是第一個和第四個<item>):
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_selected="true" android:drawable="@android:color/transparent" /> <item android:state_selected="true" android:drawable="@android:color/transparent" /> <item android:state_pressed="true" android:state_selected="false" android:drawable="@android:color/transparent" /> <item android:state_selected="false" android:drawable="@color/solid_red" /></selector>
然後在getView()裡這樣寫就可以了:
if (item.getStopId().equals(User.stopId)) { view.setBackgroundResource(R.drawable.my_row);} else { view.setBackgroundResource(android.R.drawable.list_selector_background);}
參考連結1 參考連結2 參考連結3
26、在一個TableLayout裡讓Button寬度相同並佔滿表格寬度(想象一個由按鈕組成的九宮格)
如果Button上的文字不長,按一般的方法就可以實現,例如這個連結。當Button上的文字很長,還是會使布局變亂,每個列的長度將不一樣。解決方案是將按鈕的layout_width設為0,layout_height設定為所需要的值,需要換行時將singleLine設定為false,最後將按鈕的gravity設定為center。
27、對切換畫面方向的處理
參考stackoverflow上的一個典型討論。
當MyActivity位於一個TabActivity裡時,我做了一些實驗表明, TabActivity是否聲明android:configChanges="keyboardHidden|orientation"與MyActivity無關,只有MyActivity做了上述聲明後才會在改變方向時觸發onConfigurationChanged()方法。
28、strings.xml裡的字串包含html格式標籤時
需要用<Data><![CDATA[...]]></Data>把html程式碼封裝起來。參考連結
29、在AlertDialog裡用ListAdapter(如ArrayAdapter)時,文字不顯示。
view的resourceId要用select_dialog_singlechoice而不能用simple_list_item_single_choice,否則文字顏色會與背景顏色相同而無法顯示。參考連結
30、在android程式裡使用第三方包的配置方法
參考這個連結成功。
31、定製tabhost的外觀
這方面的需求和問題網上都很多,主要的解決方案有基於tabhost的和基於radiobutton的兩大類,這裡有幾個可以參考的連結。連結1,連結2,連結3
32、取得當前螢幕方向
有好幾個方法可以得到orientation值,但一些得到的值不對,例如getWindowManager().getDefaultDisplay().getOrientation()和getReqestedOrientation()。我實驗下來比較靠譜的是getResources().getConfiguration().orientation。
33、Activity裡第一個View是EditText的時候,軟鍵盤自動彈出。
似乎只是一些機型會這樣做。要阻止軟鍵盤彈出,可在onCreate()裡加一行代碼。參考連結
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
34、Dialog的theme問題
使用Theme.Light主題時,Dialog顯示不正常。相關討論:連結1,連結2
35、注意區分CheckBox和RadioButton的OnClickListener和OnCheckedChangeListner
使用前者時,當在代碼裡執行myCheckBox.setChecked(true),不會觸發事件,而後者會觸發事件。
36、監視GPS開啟/關閉事件
用GpsStatus.Listener不可靠(事件不上來),這個連結的方法是監視Settings裡的事件:參考連結
37、模擬器橫屏
快速鍵ctrl+f11。有人提到ctrl+f12和numpad 7也可以,但我這裡不起作用。
38、用JAXB產生KML對應的Java Code時會遇到一些問題,解決方案如下:
1)寫一個binding檔案如bindings.xjb放在與ogckml22.xsd同一目錄,內容可參考這個連結(根據錯誤提示要刪除幾行)
2)在命令列裡加-extension
3)在命令列裡加-target 2.1(否則產生的java類的annotation帶有jdk6不識別的關鍵字"required")
完整的命令列如下:
xjc -xmlschema -verbose -extension -b bindings.xjb -d src -target 2.1 ogckml22.xsd
39、ListPreference的entryValues只能使用string-array
如果使用了integer-array,在點擊這個preference項時會產生一個null 指標異常,相關討論見連結1、連結2。
Update: 又發現一個ListPreference的新問題,即使用string-array,defaultValue值也不能取太大的(超過Integer.MAX_VALUE)整數,否則defaultValue不起作用(選項沒有預設被選中)。 真是問題多多。android版本2.2。
40、Android提供了方便的Share機制,但一般都是把文字share到微博或SMS,如何能"share"文字到SD卡檔案呢?
這個連結描述了同樣的問題,等待有人回答。 目前的想法是,在程式裡自己實現一個接受ACTION_SEND的activity,做法可參考此連結、或此文章。
41、一個線上查看kml檔案的網站,供參考。
GPS Visualizer
42、關於onSaveInstanceState()的使用
通常與onCreate()配合,而非onRestoreInstanceState(),參考這個連結。
43、ListView裡點擊一個item背景色不變為橘黃(預設的反饋顏色),各種OnClick事件不被觸發。
一種可能是在item的布局檔案(如foo_list_row.xml)裡使用了下面的這些屬性(自動滾動顯示文字時常會用到),去掉後即可恢複正常:
android:ellipsize="marquee" android:scrollHorizontally="true"android:marqueeRepeatLimit="marquee_forever" android:focusable="true"android:focusableInTouchMode="true"
44、實現不停向上滾動的ListView
假設你有一個長長的list需要自動展示,方式是每隔幾秒向上滾動一行,有點類似TextView的marquee功能(跑馬燈?)。這個需求可以通過Handler實現,具體參考這個連結;當列表滾動到最後一行時,直接滾回第一行顯得很生硬,可以用這個連結裡提供的方法解決。
45、在Button的文字旁加圖片
在<Button>裡使用android:drawableLeft="@drawable/my_icon" android:gravity="left|center_vertical"即可,類似的可以加在右側或上下方。但如果Button有其他狀態時,需要用selector指定不同狀態下的圖片。此外,圖片的大小是不會自動根據Button調整的。
46、舊版本相容
參考sdk文檔裡的這個文章。
47、輕鬆實現圓角背景
不需要做圓角圖片,看看這個連結,很方便,注意把angle改為45的倍數否則運行時報錯。
48、Android記憶體流失檢測
在DDMS可以查看heap使用方式,大概瞭解是否有記憶體流失。DDMS還可以dump出.hprof檔案,後者可以用Eclipse MAT開啟,進一步分析錯誤原因。注意,startActivity()後要根據情況決定是否調用finish()方法(如果需要back則不finish(),在適當的時機用FLAG_ACTIVITY_CLEAR_TOP一併回收記憶體空間),未finish()的activity是會一直佔用記憶體的。
49、Android的第三方library
這個連結總結了不少。
50、Android UI設計模式
參考這個連結。
51、Google Map擴充的使用。
參考這個連結。
52、當Spinner是invisible狀態時,貌似調用mySpinner.setSelection(i) 不會觸發其onItemSelected()事件。
53、實現gzip壓縮伺服器返回的json對象時,注意要response.setContentType("application/json"),並且在server.xml裡把application/json設定到compressableMimeType裡才能實現。我因為前一個原因浪費了三四個小時。
54、對AlertDialog.Builder應用定製的theme
使用ContextThemeWrapper,用法參考這個連結。但後來發現這個方法不起作用,有一種說法是這個方法只對部分android版本有效,也有說其根本無效的(都是在so上)。用AlertDialog.Builder的setVIew()方法也是有問題的,因為你會發現在這個view的旁邊一圈(假設你的view是淺色背景)還是黑色的,效果很不好。其實如果只是要將對話方塊設定為白色背景,可以使用AlertDialog.Builder的setInverseBackgroundForced(true)方法,很簡單,很直接。
55、從gallery選擇圖片的一些可用參數
參考這個連結,和這個相關issue (檔案得不到原始圖片,只能得到縮小後的圖片)。
56、從gallery取圖片時要注意記憶體是有限的,而圖片可能很大。
利用inSampleSize可以協助解決,參考這個連結的代碼。
57、當程式進程被系統kill掉(常常在記憶體緊張時發生):
HttpClient的session可以用persist方式保留;
其餘資料建議保留在SharedPreferenes裡;
onActivityResult()裡是能夠獲得另一個activity傳回來的intent裡的參數的;
58、串連到真機時提示Unable to open sync connection!
原因未知,解決方案是在真機的設定裡去掉usb調試,然後重新勾選。
59、得到GPS狀態(尋星或已獲得位置)
這個問題看似簡單,但Android裡的LocationListener#onStatusChanged()方法工作不正常,表現為在大多數版本下都不會被調用。這個連結裡提供的方法試了一下好像是可以用的。
60、在Android裡畫統計圖(柱圖餅圖等等)
這個連結裡給出了不少解決方案,我暫時選擇的是aChartEngine,用法和JFreechart比較類似,參數超多,目前的活躍度也不錯。
61、進程經常被kill
可以考慮啟動一個service,這樣進程的“重要性”就變得很高,因此就不容易被kill了。
62、“Receiver not registered”錯誤
執行unregisterReceiver(myReceiver)方法時,如果之前沒有註冊過myReceiver,會拋出這個異常。參考連結
63、應用在後台運行,需要彈出對話方塊(例如觸發自service產生的事件)時報錯:“BadTokenException: Unable to add window”
利用isFinishing()測試activity是否在後台,參考連結
64、Emulator太慢了?
試試Android x86,據說比官方的快很多(我還沒試過,正在下載)。 參考連結
65、禁止自動切換到橫屏模式
<activity android:name=".SomeActivity" android:label="@string/app_name" android:screenOrientation="portrait">...</acivity>
參考連結
66、幾個眾包模式的beta測試平台
iOS最著名的是testflight,也有其他一些類似的測試平台支援android,詳見這個連結。
67、實現鎖機後黑屏但不出現鎖機畫面
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
還有一個功能類似的flag是FLAG_DISMISS_KEYGUARD,區別在於前者只對當前activity有效,後者全域有效。另外前者對安全鎖屏也有效,後者則只對普通鎖屏有效。附一個參考連結。
但是前者有一個問題,就是在兩個都設定了FLAG_SHOW_WHEN_LOCKED的activity間切換時,可能鎖定畫面會閃一下。見此問題報告。
68、一些可用於android應用效能測試和記憶體流失檢測的工具
見這個連結。
69、進度條的一個bug
重設setMax()以後顯示的進度百分比不正確,至少在Android 2.1 (API Level 7)裡有這個問題。 見這個連結和這個連結。
70、當ListView的item裡包含控制項(如按鈕、複選框)時 ,這個item無法被選中。
Android不允許選中ListView裡帶有focusable元素的item,解決方案是將該控制項的focusable屬性設定為false。參考連結
71、協助做簡單web測試的工具(構造並發送各種http請求)
這個連結裡總結了不少。
72、Tab放在底部(仿iphone風格)
中文的教程看了好幾個都不靠譜,so上的一個連結搞定,或者這個帶有源碼的教程。
73、讓ListView沒有資料時也顯示HeaderView/FooterView
技巧是讓empty view包含headerview/footerview,見這個連結。
74、在Google map上添加popup的方法
最簡單的方法見這個連結。
75、一個網站,可以搜尋android相關項目的代碼和資源。
連結在此
76、Android裡的Search Activity不支援返回結果到調用其的Activity(因為onSearchRequested()方法沒有調用startActivityForResult()啟動search activity)
SO上有若干個提出此問題的文章,例如連結1、連結2等等,沒有特別方便的辦法解決,一個我沒試過但看回複應該可行的方法見這個連結。
77、查看apk檔案內容的工具
推薦apktool,一個命令列工具,用法如下:
>apktool.bat d my.apk
可以還原所有的資源檔,但.java檔案一般無法還原。
78、Android中使用的各類表徵圖的標準尺寸
請參考sdk內建的guideline文檔。
79、Android的Searchable介面,無法讓調用者獲得查詢結果。
參考這篇文檔可以實現,思路是自己用startActivityResult() 啟動搜尋介面,然後再onActivityResult()裡取出結果。我測試可行,但該文檔有兩處錯誤需要注意:
1) 是handleIntent()而非handleActivity()
2) 在startActivityResult()前最好intent.setAction(Intent.ACTION_SEARCH) 一下。
另外,注意按該文章中提到的官方文檔實現相應的newIntent()和onCreate()方法,以及在AndroidManifest.xml裡設定調用者的android:launchMode="singleTop"。
80、很詭異的問題,有時EditText無法輸入文字(軟鍵盤正常彈出但字元進不去文字框),必須切換到另一個IME才可以輸入。
經測試,有些機型存在這個問題,具體原因還不詳。以下連結可能與此有關:連結1
81、定時重複執行一段程式
要執行類似鬧鐘這樣的功能,用AlarmManager配合BroadCastReceiver即可,網上有很多例子不再贅述。值得一提的是,在這個BroadCastReceiver裡不要執行非同步作業(例如非同步訪問一個遠程服務、擷取當前位置等等),因為onReceive()方法一旦執行結束,用於容納BroadCastReceiver的進程隨時可能被系統kill掉,導致非同步作業結束後出現異常。解決的辦法是在onReceive()方法裡啟動一個Service(我用的是startService,用bindService的方式可能也行),在Service裡執行任何操作就可以了。參考BroadCastReceiver Life Cycle
82、Monkey測試
>adb shell monkey -v -p com.my.app 100
MonkeyRunner可以進行更進階的測試。
83、用getIntent().getExtras().clear()無法清除掉extras裡的資料
原因是getExtras()返回的是一個copy執行個體,用getIntent().removeExtra()可一個個清除。參考連結
84、用AlertDialog實現輸入對話方塊時,若直接builder.setView(myEditText)文字框顯得太長。
用dialog.setView()可以指定padding(注意是dialog.setView()而不是builder.setView()),具體見這個連結。
85、在TextView裡顯示圖片
通過Html.fromHtml()方法可以在TextView裡顯示HTML格式的文本,但只支援部分tag:
myTextVIew.setText(Html.fromHtml(myHtmlStr))
要在TextView裡顯示遠程圖片,必須向fromHtml()函數裡提供一個ImageGetter對象,在它的getDrawable()方法裡擷取遠程映像並轉換為Drawable類型。範例程式碼請參考此連結。
如果TextView設定了android:lineSpacingMultiplier屬性,將導致圖片顯示的位置不正確(頂部多出一些空白),用android:lineSpacingExtra屬性則沒有這個問題。
如果圖片載入比較慢將導致整個TextView空白很長時間,為解決這個問題需要非同步載入圖片,這樣文字可以先出來,待圖片下載完畢後再補充道文字中間。實現方法是擴充Drawable,具體方法參考這兩個連結:連結1、連結2 ,其中連結1的方案存在圖片尺寸不正確的問題,原因是TextView#invalidate()沒能起作用(原因不詳),用連結2提供的方法可以解決,這個連結提到用textView.setText(textView.getText())也可以工作但我沒試。
86、在TextView裡顯示列表(<li>標籤)
Android的TextView只支援一小部分的html標籤(見這個連結),預設是不支援<ol>、<ul>和<li>這樣的列表標籤的。通過TagHandler可以實現一個簡單的列表效果(見此連結),但這個方法有個嚴重問題:當列表文字超過一行時,第二行的文字是頂頭的沒有縮排效果(見這個提問),而該問題暫時還沒有好的解決方案。
(待續)