2012年4月28日 星期六

[UI] Supporting Multiple Screens - Terms and Concepts

* Terms and Concepts
  • Screen size (inch)
    • 以螢幕對角線為準,可分為small, normal, large, and extra large。
  • Aspect ratio
    • 螢幕的長寬比。
  • Resolution 解析度
    • The total number of physical pixels on a screen.
  • Density
    • pixel 密度 (the spread of pixels across the physical width and height of the screen)。
    • 可分為 low, medium, large, and extra large。
  • Density-independent pixel (dp)
    • A virtual pixel unit that applications can use in defining their UI, to express layout dimensions or position in a density-independent way。
    • pixels = dps * (density / 160)。
  • px (pixels)
    • 像素,對電腦而言,所有人眼所見的影像都是螢幕上一連串的光點的構成的,這些光點是電腦顯示的最小單位。
    • 光點的數量越多,影像提供的細節就越多。

* Range of screens supported
At run time, the platform handles the loading of the correct size or density resources, based on the generalized size or density of the current device screen, and adapts them to the actual pixel map of the screen.
  • Sizes
    • small, normal, large, and xlarge
  • Densities
    • ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)
    • The xhdpi density category was added in Android 2.2 (API Level 8). 
    • The xlarge size category was added in Android 2.3 (API Level 9).

* Android support application to display resources
  • Pre-scaling of resources (such as image assets)
  • Auto-scaling of pixel dimensions and coordinates
  • Compatibility-mode display on larger screen-sizes

* 若要指定特定長度或大小,要使用以下單位,才不會因為系統的 resolution 不同而呈現不同結果:
  • sp (scaled pixels): 用於字體。
  • dip/dp (density independent pixels): 系統會依比例呈現,使得結果不受 pixel 影響。


* Reference
- Supporting Multiple Screens
- long or notlong
- 關於android系統資源更換-語言切換或配置改變
- 屏幕分辨率
- 关于android多分辨率中的density和density-independent pixel的区别
- 何謂解析度、DPI?
- android平台下单位px,dip,sp的区别

[AndroidGraphic] Bitmap and Drawable

// drawable 轉換為 bitmap: 利用canvas物件來達成。
Bitmap drawableToBitmap(Drawable drawable) { 
    Bitmap.Config c = drawable.getOpacity() != PixelFormat.OPAQUE ? 
        Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
    Bitmap bitmap = Bitmap.createBitmap( 
        drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), c);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), 
    drawable.getIntrinsicHeight()); 
    drawable.draw(canvas); 
    return bitmap;
}

Bitmap bitmap = ((BitmapDrawable) iconDrawable).getBitmap();
new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, 128, 128, true))


// bitmap 轉換為 drawable: 利用BitmapDrawable直接轉換。
Drawable bitmapToDrawable(Bitmap bitmap) {
    Drawable drawable = new BitmapDrawable(bitmap);return drawable;
}


* Reference
- Camangi 市集 - 關發商資訊

[Multimedia] Video format

傳送方式
  • 交錯(隔行)掃瞄 (interlace, abbr: i)
    • 早年廣播技術不發達,頻寬甚低時用來改善畫質的方法。
    • 是一種將圖像顯示在掃描式的顯示設備上的方法。
    • 在同樣幀率的情況下,這種方法比起逐行掃描引起的視覺閃爍比較小。
    • ex: NTSC, PAL, SECAM, 陰極射線管(CRT for Cathode Ray Tube)。
  • 循序掃瞄 (Progressive, abbr: P)
    • 是一種在顯示設備表示運動圖像的方法,這種方法將每幀的所有像素同時顯示(逐行掃描有時候被稱為非隔行掃描)。
    • 每次畫面更新時都會刷新所有的掃瞄線。
    • 此法較消耗頻寬但是畫面的閃爍與扭曲則可以減少。
    • 為了將原本為交錯掃瞄的視訊格式(如DVD或類比電視廣播)轉換為循序掃瞄顯示設備(如LCD電視,電漿電視等)可以接受的格式,許多顯示設備或播放設備都具備有去交錯的程序。但是由於交錯信號本身特性的限制,去交錯並無法達到與原本就是循序掃瞄的畫面同等的品質。
    • 常被用在計算機顯示器上。通常的顯示器的掃描方法都是從左到右從上到下,每秒鐘掃描固定的幀數(稱為幀率,例如60幀每秒)。

色彩
  • 色彩空間(Color Space)或色彩模型(Color model name)規定了視訊當中色彩的描述方式。
  • ex: NTSC 電視使用了 YIQ 模型,而 PAL 使用了 YUV 模型,SECAM 使用了 YDbDr 模型。
  • 在數位視訊當中,像素資料量(bits per pixel,簡寫為 bpp)代表了每個像素當中可以顯示多少種不同顏色的能力。由於頻寬有限,所以設計者經常藉由色度抽樣之類的技術來降低 bpp 的需求量。

H.263
  • 由 ITU-T 制定的視頻會議用的低碼率視頻編碼標準,屬於視頻編解碼器。
  • 最初設計為基於 H.324 的系統進行傳輸(即基於公共交換電話網和其它基於電路交換的網路進行視頻會議和視頻電話)。
  • 下一代視頻編解碼器是 H.264,或者叫 AVC 以及 MPEG-4 第10部分。由於 H.264 在性能上超越了 H.263 很多,現在通常認為 H.263 是一個過時的標準。

H.264/MPEG-4 AVC
  • 是由 ITU-T 視頻編碼專家組(VCEG)和 ISO/IEC 動態圖像專家組(MPEG)聯合組成的聯合視頻組(JVT,Joint Video Team)提出的高度壓縮數字視頻編解碼器標準。
  • JVT 編解碼器 (由於該標準是由 JVT 組織並開發的)
  • ITU-T 的 H.264 標準和 ISO/IEC MPEG-4第10部分(正式名稱是ISO/IEC 14496-10)在編解碼技術上是相同的,這種編解碼技術也被稱為 AVC(進階視訊編碼, Advanced Video Coding。
  • 標準第一版的最終草案已於2003年5月完成。
  • 此標準有以下稱呼來明確的說明它兩方面的開發者:
    • H.264/AVC
    • AVC/H.264
    • H.264/MPEG-4 AVC
    • MPEG-4/H.264 AVC

MPEG (通常指MPEG-1)
  • Moving Picture Experts Group。
  • 本來的含義是指一個研究視頻和音頻編碼標準的「動態圖像專家組」組織,成立於1988年,致力開發視頻、音頻的壓縮編碼技術,至今已經制定了MPEG-1、MPEG-2、MPEG-3、MPEG-4、MPEG-7等多個標準,。
  • 現在我們所說的 MPEG 泛指由該小組制定的一系列視頻編碼標準。
  • 是基於變換的有損壓縮。光學信號線經過採樣形成視頻信號,視頻信號基本的單位叫做影格,一個影格就是一個獨立的圖像,然後影格被分割成小塊做變換編碼,然後量化,最後進行熵編碼。
  • 與傳統影像編碼技術不同,MPEG 並不是每格影像進行壓縮,而是以一秒時段作為單位,將時段內的每一格影像做比較,由於一般視頻內容都是背景變化小、主體變化大,MPEG 技術就應用這個特點,以一幅影像為主圖,其餘影像格只記錄參考資料及變化數據,更有效記錄動態影像。從MPEG-1到MPEG-4,其核心技術仍然離不開這個原理,之間的分別主要在於比較的過程和分析的複雜性等。
  • MPEG 只規定位元流的格式與解碼精確度(即規定解碼的方法),而任何人可依照MPEG標準以不同方式實現編碼器(程式)。
  • 除了可減少因編碼專利造成的商業利益糾紛外,MPEG標準的主要目的在於確保不同的編碼器所產生的位元流可被其他解碼器正確的解碼,只要此位元流符合標準。

720p
  • 是一種視頻顯示格式。
  • 字母 p 意為逐行掃描(progressive scan),數字 720 則表示垂直方向有 720 條掃描線。
  • 通常畫面解析度為 1280 × 720,一般亦可稱為高畫質(HD)
  • 但有些情況下,如iPod Touch 4,其720P攝錄並不是指1280×720(16:9),而是960×720(4:3),故沒有註明是HD的720P攝錄並不是都指1280×720(16:9)。


新的高畫質電視(HDTV)解析度可達1920x1080p60,即每條水平掃瞄線有1920個像素,每個畫面有1080條掃瞄線,以每秒鐘60張畫面的速度播放。

* Reference
- 影片
- 隔行掃描
- 逐行掃描
- H.263
- MPEG
- H.264/MPEG-4 AVC
- JVT
- 720p
- 頗析 720p, 1080i 和 1080p

[Android] INSTALL_FAILED_CONFLICTING_PROVIDER

Error Message
[2010-02-28 04:14:38 - mobileFinder]Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER
[2010-02-28 04:14:38 - mobileFinder]Please check logcat output for more details.
[2010-02-28 04:14:38 - mobileFinder]Launch canceled!


Solution
在安裝 apk 時,系統便會依 AndroidManifast.xml 中的宣告註冊

android:authorities 在系統中不可重覆。


* Reference
- Android: INSTALL_FAILED_CONFLICTING_PROVIDER « Hustle Play

[SQL] AND has more priority than OR

* Priority
  • In SQL: AND > OR
  • In Java: && > ||

SELECT count(*) FROM TABLE_A
    WHERE (X= 2 OR X = 5) AND Y = 0;
   
SELECT count(*) FROM TABLE_A
    WHERE X IN (2,5) AND Y = 0;


2012年4月21日 星期六

[AndroidNet] HTTP API

Android includes two HTTP clients: HttpURLConnection and Apache HTTP Client. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6 and connection pooling.

  • android.net.http.AndroidHttpClient - API 8 - 主要使用 Apache 的 HttpClient
    • Implementation of the Apache DefaultHttpClient that is configured with reasonable default settings and registered schemes for Android, and also lets the user add HttpRequestInterceptor classes. 
    • Don't create this directly, use the newInstance(String) factory method.

Their implementation is stable and they have few bugs. But Android Team is not actively working on Apache HTTP Client.


  • abstract java.net.URLConnection
    • Instances of URLConnection are not reusable: you must use a different instance for each connection to a resource.
    • An URLConnection for HTTP (RFC 2616) used to send and receive data over the web. Data may be of any type and length.
  • java.net.HttpURLConnection extends URLConnection
    • This class may be used to send and receive streaming data whose length is not known in advance.
    • Is a general-purpose, lightweight HTTP client suitable for most applications.
    • Prior to Froyo, HttpURLConnection had some frustrating bugs.
    • Work around this by disabling connection pooling (Refer:  Android’s HTTP Clients | Android Developers Blog)
    • In Gingerbread, we added transparent response compression.
    • In Ice Cream Sandwich, we are adding a response cache.

  • How to choose?
    • Eclair and Froyo  - Apache HTTP client that has fewer bugs.
    • For Gingerbread and better -  HttpURLConnection.
      • Its simple API and small size makes it great fit for Android.
      • Transparent compression and response caching reduce network use, improve speed and save battery.
      • Android Team will be spending our energy going forward.

* Reference
- Android’s HTTP Clients | Android Developers Blog
- Android 上的 HTTP 服務相關函式 (I)
- Android 上的 HTTP 服務相關函式 (II)
- Android 上的 HTTP 服務相關函式 (III)

2012年4月15日 星期日

[AndroidDev] Designing for Performance

  • Battery life is one reason you might want to optimize your app even if it already seems to run “fast enough”.
  • Choosing the right algorithms and data structures should always be your priority.
    • Using the right data structures and algorithms will make more difference than any of the advice here
  • Considering the performance consequences of your API decisions will make it easier to switch to better implementations later (this is more important for library code than for application code).
  • Different versions of the VM running on different processors running at different speeds.
  • There are also huge differences between devices with and without a JIT: the “best” code for a device with a JIT is not always the best code for a device without.

There are two basic rules for writing efficient code:
  • Don’t do work that you don’t need to do.
  • Don’t allocate memory if you can avoid it.


Avoid Creating Unnecessary Objects *
過多物件會占據太多空間,觸使系統 GC 的頻率變高,而在 GC 時會使得使用者在操作中感覺頓頓的,因為系統會暫停(lock)所有東西。
  • Fewer objects created mean less-frequent garbage collection, which has a direct impact on user experience.
  • If you allocate objects in a user interface loop, you will force a periodic garbage collection, creating little “hiccups” in the user experience.
  • 改善範例: 
    • 如果回傳的字串會再 append 到 StringBuffer,那麼可以直接傳入 StringBuffer 去 append 字串。
    • When extracting strings from a set of input data, try to return a substring of the original data, instead of creating a copy. You will create a new String object, but it will share the char[] with the data. (The trade-off being that if you’re only using a small part of the original input, you’ll be keeping it all around in memory anyway if you go this route.)
    • 使用一維矩陣取代多維矩陣;使用 primitive types array instead of Object type array. 
      • But this also generalizes to the fact that two parallel arrays of ints are also a lot more efficient than an array of (int,int) objects.
      • But tuples of two-dimension objects is usually better to trade good API design for a small hit in speed. 

Performance Myths
  • On devices without a JIT
    • 型別有指定特定的 type 會比使用 interface 有效率。For example, it was cheaper to invoke methods on a HashMap map than a Map map, even though in both cases the map was a HashMap
    • Caching field accesses is about 20% faster than repeatedly accesssing the field. 
  • With a JIT, field access costs about the same as local access, so this isn’t a worthwhile optimization unless you feel it makes your code easier to read. (This is true of final, static, and static final fields too.)

Prefer Static Over Virtual
If you don’t need to access an object’s fields, make your method static.

Avoid Internal Getters/Setters
  • Virtual method calls are expensive, much more so than instance field lookups.
  • It’s reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Use Static Final For Constants
This optimization only applies to primitive types and String constants, not arbitrary reference types. Still, it’s good practice to declare constants static final whenever possible.
// Compiler 會產生  method(a class initializer method),在第一次使用這個 class 時會被執行。
// The method stores the value 42 into intVal, and extracts a reference from the classfile string constant table for strVal.
// When these values are referenced later on, they are accessed with field lookups.
static int intVal = 42;
static String strVal = "Hello, world!";
We can improve matters with the “final” keyword:
// 不會產生  method,因為常數會存在於 dex file 的 static field initializers。
// Code that refers to intVal will use the integer value 42 directly, and accesses to strVal will use a relatively inexpensive “string constant” instruction instead of a field lookup. 
static final int intVal = 42;
static final String strVal = "Hello, world!";

Use Enhanced For Loop Syntax (i.e for-each loop)
  • The enhanced for loop can be used for collections that implement the Iterable interface and for arrays.
  • 只要是 Collection 介面的實作物件,都可以用 foreach 語法,新增於 J2SE 5.0 之後。
// 如果走訪的是陣列,編譯器會自動展開為以下的程式碼:
public void go(int ai[]) {
    int ai1[] = ai;
    int i = ai1.length;
    for (int j = 0; j < i; j++) {
        int k = ai1[j];
        System.out.println(k);
    }
}

// 若是 Collection 的實作物件,其實編譯器會展開為:
public void go(Collection collection) {
    String s;
    for (Iterator iterator = collection.iterator(); 
        iterator.hasNext(); System.out.println(s))
        s = (String)iterator.next();
}

// 無論是 Collection、List 或 Set,展開後皆利用 iterator() 方法傳回 Iterator 物件,
// 並利用 Iterator 來移動、傳回下一個物件,這是 Iterator 模式 的實現。
// 所以其實在 for-each 中會多產生個 Iterator 物件,因此可寫成以下程式。
public void go(Collection collection) {
    if (collection.size() > 0)
        for(String element : collection) {
            System.out.println(element);
        }
}
To summarize:
  • Collections 使用 for-each loop; ArrayList 使用 for loop(?)。
    • Use the enhanced for loop by default, but consider a hand-written counted loop for performance-critical ArrayList iteration.
    • With an ArrayList, a hand-written counted loop is about 3x faster (with or without JIT), but for other collections the enhanced for loop syntax will be exactly equivalent to explicit iterator usage.

Consider Package Instead of Private Access with Private Inner Classes
Inner class 使用 Package(default) modifier,而不要使用 Private。
public class Foo {
    private class Inner {
        void stuff() {
            Foo.this.doStuff(Foo.this.mValue);
        }
    }

    private int mValue;

    public void run() {
        Inner in = new Inner();
        mValue = 27;
        in.stuff();
    }

    private void doStuff(int value) {
        System.out.println("Value is " + value);
    }
}

因為 VM 會認為從 Foo$Inner 直接去存取 Foo 的 private member 是不合法的(Foo and Foo$Inner are different classes),因此 compiler 會產生下列 methods(Accessors),也就是 Foo$Inner 事實上是透過這些 methods 來存取 Foo 中的 private members。
// package
static int Foo.access$100(Foo foo) {
    return foo.mValue;
}
// package
static void Foo.access$200(Foo foo, int value) {
    foo.doStuff(value);
}
Accessors are slower than direct field accesses! 所以將 inner class 宣告為 Package,但這樣也表示此 inner class 可以直被同個 package 下的 classes 存取,因此不可使用在 public API.

Use Floating-Point Judiciously
避免使用 float type。

Know And Use The Libraries

Use Native Methods Judiciously
  • Native code isn’t necessarily more efficient than Java. For one thing, there’s a cost associated with the Java-native transition, and the JIT can’t optimize across these boundaries.
  • Native code is primarily useful when you have an existing native code base that you want to port to Android, not for “speeding up” parts of a Java app.

Closing Notes
  • One last thing: always measure
  • Before you start optimizing, make sure you have a problem. Make sure you can accurately measure your existing performance, or you won’t be able to measure the benefit of the alternatives you try.


* Reference
- Designing for Performance
- 繼承
- Android App開發效能你知多少?
- Dalvik 記憶體管理
- Just-in-time compilation
- 初探JIT compiler 與 Android Dalvik VM
- Profiling with Traceview and dmtracedump
- Java Gossip: autoboxing、 unboxing
- Java Essence: 神奇的 foreach

[Tool] Memory Analyzer Tool (MAT)

雖然現在手機在硬體上的限制已不如從前,效能也大大提升,但手機中的空間還是不比在電腦上,所以如果不需過多的 effort,盡量降低空間的使用仍是必要的,使用者很容易就安裝過多的 App 或是同時操作多個 App,那麼一個 App 能降低一點使用量,我認為全部加起來多少會有點影響,但並不說要在一開始開發時便以效能為一取向,這樣反而有點綁手綁腳,本末倒置了,除非效能是需求之一。

尤其在某些 UI 的操作上,若系統進行 Garbage Collection,則會讓 User 在操作時感覺到頓頓的,另外,圖片上的使用,很容易使得 App Out Of Memory(OOM)(每個 App 被分配的空間是 16M),因此可利用 Eclipse plugin - MAT 來找出在 App 中是那裡使用了大量空間,而且沒有做適當的釋出。

Install
  • Install MAT Plugin on Eclipse - Install New Software
    • http://download.eclipse.org/mat/1.1/update-site/
  • 開啟關閉 App 約五次,來觀察是否有正確的建立與回收物件
  • Dump HPROF file by DDMS
  • Convert HPROF format by Android Tool, hprof-conv
  • Open eclipse perspective, Memory Analyer and File --> Open Heap Dump...

  • Shallow Heap
    • 物件本身的記憶體使用量。
  • Retained Heap
    • 指物件本身 + 參照過來的物件們所使用的記憶體使用量。

如何妥善的使用 bitmap
Displaying Bitmaps Efficiently


* Reference
- 使用MAT(記憶體分析)工具查看Memory Leak ***
- HOWTO: Debug Memory Leak in Android
- Download MAT
- Android Memory Usage
- Avoiding memory leaks - Romain Guy ***
- Attacking memory problems on Android ***

2012年4月3日 星期二

[AndroidManifest] Two launch icons


  • If set two launched icons in an apk.
    • Two launcher with their own settings.
    • Default launch the first one when launched by debug mode.


2012年4月1日 星期日

[AndroidDev] merge

  • The <merge /> tag was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees.
  • 如果 root layout 的大小設為和 parent 一樣 (ex: filll_parent)並且沒其他參數調整需求,那麼其實此 root layout 在實質上是沒有作用的,這時候便可以改以 merge 做為你的 root layout,這樣一來 children 便會直接被加在 merge's parent 上而能少拉一層 view。
    • Since our FrameLayout has the same dimension as its parent, by the virtue of using the fill_parent constraints, and does not define any background, extra padding or a gravity, it is totally useless.When the LayoutInflater encounters this tag, it skips it and adds the <merge /> children to the <merge /> parent. (The children will be added directly to the top-level FrameLayout.)
  • 但 merge 是不能用來取代 LinearLayout 的!
    • You could not apply this trick if your layout was using a LinearLayout as its root tag for instance. The <merge /> can be useful in other situations though.

  • The <merge /> tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitations:
    • <merge /> can only be used as the root tag of an XML layout
    • When inflating a layout starting with a <merge />, you must specify a parent ViewGroup and you must set attachToRoot to true (see the documentation for inflate(int, android.view.ViewGroup, boolean) method)


* Reference
- Layout Tricks: Merging Layouts | Android Developers
- Android里merge和include标签的使用_云开雾散_百度空间

[AndroidDev] Window Backgrounds & UI Speed

In this article, you will discover how to speed up the drawing and the perceived startup time of your activities. Both these techniques rely on a single feature, the window's background drawable.

  • When you setup your user interface by calling setContentView() on an Activity.
  • 該 activity's window 會被加上你所設的 view 以及 Android 為你所建立的 views。(其中最重要的是 DecorView.)
    • Android adds your views to the Activity's window. The window however does not contain only your views, but a few others created for you. (The most important one is, in the current implementation is the DecorView.)
  • The DecorView is the view that actually holds the window's background drawable.
  • 藉由呼叫 getWindow().setBackgroundDrawable() 便可以改變 activity's window background 也就是 DecorView's background drawable.
  • If you are using the standard Android themes, a default background drawable is set on your activities. The standard theme currently used on the T-Mobile G1 uses for instance a ColorDrawable.
  • 但此預設背景其實是會影響效能的!
  • An easy way to make such an application draw faster is to remove the background drawable. Since the user interface is entirely opaque, drawing the background is simply wasteful. Removing the background improves the performance quite nicely.
  • Removing the window's background can be achieved very easily by using a custom theme. To do so, first create a file calledres/values/theme.xml containing the following:
    
        
    
    
  • This trick comes in very handy for any app that uses a MapView, a WebView or any other full screen opaque view.

  • Using a theme to change the window's background is also a fantastic way to improve the perceived startup performance of some of your activities. This particular trick can only be applied to activities that use a custom background, like a texture or a logo.
  • 如果是在 XML layout 或是 onCreate() 中設定背景,那麼 user 開啟 activity 時會先看到 default theme and its dark background. 等到 content view and first layout/drawing 被 inflate 才會顯示你所設定的背景。
    • If this application simply set the wooden background in the XML layout or in onCreate() the user would see the application startup with the default theme and its dark background. The wooden texture would only appear after the inflation of the content view and the first layout/drawing pass.
  • 改善方式:
    • 將背景設定在 activity theme 中,這樣系統在 application 開始時會已最快的速度載入該 theme,所以 user 再也不會先看到 default background。
      • Instead, the application defines the wooden background in a theme, picked up by the system as soon as the application starts. The user never sees the default theme and gets the impression that the application is up and running right away.
    • ex: The same exact trick is used in the Google Maps application that ships with the T-Mobile G1. When the application is launched, the user immediately sees the loading tiles of MapView. This is only a trick, the theme is simply using a tiled background that looks exactly like the loading tiles of MapView.


* Reference
- Android Developers Blog: Window Backgrounds & UI Speed