心血來潮做了一個調查:iOS 和 Android 哪個問題比較多?
Android 429,364
http://stackoverflow.com/questions/tagged/android
iOS 197,651
http://stackoverflow.com/questions/tagged/ios
iPhone 186,143
http://stackoverflow.com/questions/tagged/iphone
iPad 28,707
http://stackoverflow.com/questions/tagged/ipad
Android 表示:你們三個就算重複報名加起來還是輸我啦 XD
2013年12月18日 星期三
2013年12月9日 星期一
Do not put EditText In ListView, Use ScrollView Instead
由於有個需求需要控制好記憶體用量,因此決定在 ListView 內塞 EditText,但是因為鍵盤跳出時要能夠讓 ListView 依然能夠捲到最底,因此設上 android:windowSoftInputMode="adjustResize" ,但會讓 ListView 改變大小重畫,導致 EditText 失去 focus 狀態。
因此將 Activity 設為 android:windowSoftInputMode="adjustPan" 避免這種問題。 但是卻又因為這樣會不讓 View 正確的縮小。
所以到最後還是以 ScrollView 實作,並設上 android:windowSoftInputMode="adjustResize" 在鍵盤跳出時更改 ScrollView 的大小,至於圖片的記憶體控管暫時沒有實作,等待日後需要放進大量圖片時再做修正。
因此將 Activity 設為 android:windowSoftInputMode="adjustPan" 避免這種問題。 但是卻又因為這樣會不讓 View 正確的縮小。
所以到最後還是以 ScrollView 實作,並設上 android:windowSoftInputMode="adjustResize" 在鍵盤跳出時更改 ScrollView 的大小,至於圖片的記憶體控管暫時沒有實作,等待日後需要放進大量圖片時再做修正。
Android WebView Will Not Trigger WebViewClient.shouldOverrideUrlLoading When Click Anchor
Android 的 WebView 在點選頁面上的 anchor 時是不會觸發到 shouldOverrideUrlLoading 的。
如:
<a href="#myanchor" target="_blank">不會觸發</a>
<a href="http://www.google.com#myanchor" target="_blank">會觸發</a>
小小抱怨一下,Android 的 WebView 的眉眉角角已經多到足夠特地開一個 Tag 出來寫了XD
如:
<a href="#myanchor" target="_blank">不會觸發</a>
<a href="http://www.google.com#myanchor" target="_blank">會觸發</a>
小小抱怨一下,Android 的 WebView 的眉眉角角已經多到足夠特地開一個 Tag 出來寫了XD
2013年10月16日 星期三
Application Cannot Launch From Eclipse
當程式要測試時出現 ActivityManager: java.lang.SecurityException: Permission Denial
且程式無法自動跑起來。
有兩種可能性:
且程式無法自動跑起來。
有兩種可能性:
- 重複定義了兩個 Launcher 的 Activity 在 AndroidManifest.xml,如:連結
拿掉其中一個定義即可。 - 修改了 Launcher 沒有 Clean ,導致 Launcher 不合。
Refresh、Clean 過重新執行即可。
2013年10月7日 星期一
Genymotion Multi Touch On MacOSX
在 Mac 版的 Genymotion 的多點觸控用法為
- 縮放:放大 Ctrl + 左鍵按下往左拖,縮小 Ctrl + 左鍵按下往右拖
- Zoom In:Ctrl + Mouse Drag Left
- Zoom Out:Ctrl + Mouse Drag Right
- 俯角:前傾 Ctrl + 左鍵按下往上拖,後傾 Ctrl + 左鍵按下往下拖
- Tilt Forth:Ctrl + Mouse Drag Up
- Tilt Back:Ctrl + Mouse Drag Down
- 旋轉:逆時鐘旋轉 Ctrl + Shift + 左鍵按下往左拖,順時鐘旋轉 Ctrl + Shift + 左鍵按下往右拖
- Counterclockwise Rotation:CTRL + Shift + Mouse Drag Left
- Clockwise Rotation:CTRL + Mouse Drag Right
2013年10月1日 星期二
Eclipse Trace Code Tips On OSX
以 OSX 上的 Eclipse Java Editor 為例
記錄一下裡面常用的一些預設熱鍵
修正錯誤提示:Command + 1
重新命名變數或函式:Command + 2 然後按 R
註解單行:Command + /
刪除單行:Command + D
移到行末:Command + →
跳到上一個看的位置:Command + [
跳到下一個看的位置:Command + ]
查詢變數或函式上的引用地方:Command + Shift + G
查詢 Class 繼承:Command + T
同場加映大抄:http://isagoksu.com/2009/development/developer-tools/dislikes/eclipse/osx-keyboard-binding-cheat-sheet/
記錄一下裡面常用的一些預設熱鍵
1. 檔案管理
重新整理:F5
關閉目前檔案:Command + W
關閉全部檔案:Command + Shift + W
關閉全部檔案:Command + Shift + W
儲存目前檔案:Command + S
2. 編輯
自動補完:Option + /修正錯誤提示:Command + 1
重新命名變數或函式:Command + 2 然後按 R
註解單行:Command + /
刪除單行:Command + D
2.1 游標
移到行首:Command + ←移到行末:Command + →
3. 瀏覽
跳到該變數或函式的定義:Command + 滑鼠左鍵跳到上一個看的位置:Command + [
跳到下一個看的位置:Command + ]
查詢變數或函式上的引用地方:Command + Shift + G
查詢 Class 繼承:Command + T
同場加映大抄:http://isagoksu.com/2009/development/developer-tools/dislikes/eclipse/osx-keyboard-binding-cheat-sheet/
2013年8月27日 星期二
ClassNotFoundException After Update Android SDK Tool Update To v22.0.x
很多人升上 Android SDK Tools v22.x.x 以後,原本可以執行的專案就會遇到 ClassNotFoundException,但是明明就可以 Build 起來。
這時候就要去 Build Path 的 Order and Export 裡面將 Android Private Libraries 勾起來。
這時候就要去 Build Path 的 Order and Export 裡面將 Android Private Libraries 勾起來。
2013年8月8日 星期四
Android Change android:installLocation From auto To preferExternal
在 AndroidManifest.xml 內的安裝位置原本無設定,更新成有設為 preferExternal 的版本在重開機以後會讓 App 消失。
步驟如下:
步驟如下:
- 安裝舊版
- 打開 App,確認正常
- 重開機
- 打開 App 確認依然正常
- 安裝新版 App
- 打開 App 確認正常
- 重開機
- Galaxy Note (GT-N7000)
- Sony xperia s LT26i
- Galaxy S II (GT-I9100)
2013年7月21日 星期日
Git Diff Changed File Between Two Commit
git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT COMMIT1 COMMIT2
將其中的 commit1 和 2 換成想比較的兩個 commit 即可。
如果只想複製出有更新的檔案
cp $(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT COMMIT1 COMMIT2) PATH_TO_TARGET
將其中的 commit1 和 2 換成想比較的兩個 commit 即可。
如果只想複製出有更新的檔案
cp $(git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT COMMIT1 COMMIT2) PATH_TO_TARGET
Android Scan File Cause Global Reference Table Overflow (max=51200)
Android 4.x (版本不確定,已知版本 4.1.1、4.2.2),如果極端大量且快速的執行寫檔後馬上 scanFile 的動作,會造成 JNI ERROR (app bug): global reference table overflow (max=51200),詳細原因見官方 Issue:Issue 53914
如果遇到這種問題,就在最後再執行一次完整 scanFile 避掉,而非每存一個檔案就進行一次 scanFile 。
如果遇到這種問題,就在最後再執行一次完整 scanFile 避掉,而非每存一個檔案就進行一次 scanFile 。
2013年7月17日 星期三
Android Context.startActivity From Uri Must Catch ActivityNotFoundException
如果 Intent 是用 Uri.parse 出的,在 startActivity 時請一定要 try catch ActivityNotFoundException。
例如:大部分的 Android 裝置都會有 Google Play,但是有些可能是白牌手機之類的,這時候如果想要去呼叫 Google Play 就會出現 ActivityNotFoundException。
所以如果不想管這麼多,就是只要用 Uri 或甚至是 package name 去 startActivity 的都要處理,除非有先用其他方式檢查過要開到的 Activity 是否存在。
例如:大部分的 Android 裝置都會有 Google Play,但是有些可能是白牌手機之類的,這時候如果想要去呼叫 Google Play 就會出現 ActivityNotFoundException。
所以如果不想管這麼多,就是只要用 Uri 或甚至是 package name 去 startActivity 的都要處理,除非有先用其他方式檢查過要開到的 Activity 是否存在。
2013年7月16日 星期二
Android Notification PendingIntent Received Old Intent
在 Android 中遇到點了 Notification 但是 Activity 卻的 onNewIntent 收到舊的 Intent 的狀況。
有兩種解法,各有各的用途和適合情況。
1. 在 PendingIntent.getActivity(context, requestCode, intent, flag) 的 flag 傳入 PendingIntent.FLAG_UPDATE_CURRENT
這種作法會在 requestCode 相同,但收到多個 Notification 時,只會保留最後的 PendingIntent。
官方文件說 requestCode 沒有用到是騙~人~的!
適合用在如只需要保留最後最新的資訊用到。
2. 在 PendingIntent.getActivity(context, requestCode, intent, flag) 的 requestCode 傳入 count
這個 count 是用來計算這是發第幾個通知。通常會和 NotificationManager.notify(count, pendingIntent) 用同一個。
這適合用在每則通知都要傳入不同的通知訊息內容時使用。
有兩種解法,各有各的用途和適合情況。
1. 在 PendingIntent.getActivity(context, requestCode, intent, flag) 的 flag 傳入 PendingIntent.FLAG_UPDATE_CURRENT
這種作法會在 requestCode 相同,但收到多個 Notification 時,只會保留最後的 PendingIntent。
官方文件說 requestCode 沒有用到是騙~人~的!
適合用在如只需要保留最後最新的資訊用到。
2. 在 PendingIntent.getActivity(context, requestCode, intent, flag) 的 requestCode 傳入 count
這個 count 是用來計算這是發第幾個通知。通常會和 NotificationManager.notify(count, pendingIntent) 用同一個。
這適合用在每則通知都要傳入不同的通知訊息內容時使用。
2013年7月4日 星期四
GenyMotion - The Faster Android Emulator
GenyMotion 是一個 Android 的模擬器,不像 Google 提供的慢吞吞模擬器,速度快很多。
裡面的映像檔有提供諸如:Nexus One、Nexus S、Galaxy Nexus、Nexus 7...等等各種尺寸的映像檔。也有 Google Play 可以讓你下載程式回來用,換句話說測試或是想拿來轉轉神魔之塔也可以用這個。
目前還沒開始收費。
安裝方式:
1. 先下載安裝 Virtual Box 的 MacOS 版,官網:https://www.virtualbox.org/wiki/Downloads
2. 下載安裝 GenyMotion,官網:https://cloud.genymotion.com/
註冊時,這個帳號之後用來下載映像檔也會用到。
Have a nice emulator :p
2013年6月20日 星期四
Detect Android App Not In Foreground
在 iOS 只要寫在 UIApplicationDelegate 的 applicationdidenterbackground: 就可以。
但是在 Android 要做到相同功能就沒這麼簡單了。
其中用 getRunningTasks 又只限定在 debug 時可以用,真正上到 Google Play 是不能用的。因此就必須要在 onStop() 和 onWindowFocusChange(boolean) 做一些狀態判斷,看看是不是有任何一個 Activity 在前景。
參考:
http://vardhan-justlikethat.blogspot.in/2013/05/android-solution-to-detect-when-android.html
但是在 Android 要做到相同功能就沒這麼簡單了。
其中用 getRunningTasks 又只限定在 debug 時可以用,真正上到 Google Play 是不能用的。因此就必須要在 onStop() 和 onWindowFocusChange(boolean) 做一些狀態判斷,看看是不是有任何一個 Activity 在前景。
參考:
http://vardhan-justlikethat.blogspot.in/2013/05/android-solution-to-detect-when-android.html
2013年4月30日 星期二
Android Start Activity With ACTION_VIEW Cause ActivityNotFoundException
因為並不能保證所產生的 Intent 一定能夠找到可以用來處理的程式。
所以只要有用到 ACTION_VIEW 的都要加上 catch ActivityNotFoundException
防止程式當掉。
常見的如 WebView
2013年4月10日 星期三
Separate Production And Development/Test/Beta Environments
在 Android 上不像 iOS 一樣可以很方便的用 Application ID 能夠在同一支手機上面裝好幾個一樣的 App,來測試正式和測試環境。
但是網路上大家的說法都是修改 AndroidManifast.xml 中的 package 去產生成兩個 App。
確實這樣是變成兩個 App 沒錯,但是要做這件事情可是大工程,連帶有很多東西也都必須要跟著改。加上 Google 提供的工具也兩光兩光的。
如:R 檔都要全部重新 import、有用到自訂 Attr 的 xmlns 也都要改、Google Maps v2 API Key因為有對應到 package 也要改…
但是又不太想寫 shell script 去做這件事情,因此目前是想到可以用 activity-alias 加上 meta-data 來完成切換正式和測試環境。
不過這個方法也是有缺點:因為其實這樣還是同一個 App,所以如果有資料是存在 DB、SharedPreferences 或是其他地方也都會共用到,因此有時候可能需要清除資料才行。
流程如下:
程式碼如下:
在 AndroidManifest.xml 內
在 Activity 內
但是網路上大家的說法都是修改 AndroidManifast.xml 中的 package 去產生成兩個 App。
確實這樣是變成兩個 App 沒錯,但是要做這件事情可是大工程,連帶有很多東西也都必須要跟著改。加上 Google 提供的工具也兩光兩光的。
如:R 檔都要全部重新 import、有用到自訂 Attr 的 xmlns 也都要改、Google Maps v2 API Key因為有對應到 package 也要改…
但是又不太想寫 shell script 去做這件事情,因此目前是想到可以用 activity-alias 加上 meta-data 來完成切換正式和測試環境。
不過這個方法也是有缺點:因為其實這樣還是同一個 App,所以如果有資料是存在 DB、SharedPreferences 或是其他地方也都會共用到,因此有時候可能需要清除資料才行。
流程如下:
- 程式每次按返回鍵完全關掉再去點另外一個環境,才會真的切換環境。因為我並不想讓人在程式執行中就能夠切換環境,怕搞混。
- activity-alias 如果沒有重新讀取桌面的話,暫時不會出現 / 消失,所以可能要整個移除或重開機才會看到他對應出現或消失。
程式碼如下:
在 AndroidManifest.xml 內
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0.0">
...
<application
android:icon="@drawable/ic_launcher"
android:label="@string/application_name"
android:theme="@style/Theme" >
<activity android:name=".WelcomeActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias
android:enabled="true"
android:name=".Welcome-Beta"
android:label="Beta版"
android:icon="@drawable/ic_launcher"
android:targetActivity=".WelcomeActivity">
<meta-data android:name="production" android:value="false"/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
...
</application>
</manifest>
在 Activity 內
public class WelcomeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean production = true;
try {
ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
Bundle meta = info.metaData;
if(null != meta) {
production = meta.getBoolean("production", true);
}
} catch (NameNotFoundException e) {
Log.i(TAG, "Use production as target");
}
ApplicationConfigs.setTarget(production ? Stage.PRODUCTION : Stage.BETA);
}
}
在 ApplicationConfigs.java 內
public class ApplicationConfigs {
public enum Stage {
BETA,
PRODUCTION
}
private static Stage stage = Stage.PRODUCTION;
public static void setTarget(Stage target) {
stage = target;
}
private static String getEndPoint() {
switch(stage) {
case BETA:
return "http://beta.example.com";
default:
case PRODUCTION:
return "http://www.example.com";
}
}
}
訂閱:
文章 (Atom)