2010年12月6日 星期一

修正TabWidget無法顯示問題

TabWidget在eclipse/ADT中,始終無法正確顯示UI, 有討論串討論修正TabWidget無法顯示問題
http://code.google.com/p/android/issues/detail?id=2021


To applied this fix you have to build AOSP SDK and ADT plugin with changes.
You could try something like the following:
1) download android source

$ mkdir mydroid
$ cd mydroid 
$ repo init -u git://android.git.kernel.org/platform/manifest.git
$ repo sync

2) apply changes

$ repo download platform/frameworks/base 19189/2
$ repo download platform/sdk 19190/2

3) build SDK

$ . ./build/envsetup.sh
$ lunch sdk-eng
$ make -j4 sdk

You will get AOSP SDK in ./out/host/linux-x86/sdk/android-sdk_eng.snpe_linux-x86.zip
Unpack it in some directory.

4) build ADT

$ mkdir ~/adt-destionation
$ cd /sdk
 is mydroid
$ export ECLIPSE_HOME=
$ ./eclipse/scripts/build_server.sh ~/adt-destionation
You will get ADT plugins and features in ~/adt-destionation (zip archive).
$ cd $ECLIPSE_HOME/dropins
$ mkdir adt
$ cd adt
$ mkdir eclipse
$ cd eclipse
$ mkdir features plugins
Unpack ADT zip - plugin's jar in the $ECLIPSE_HOME/dropins/adt/eclipse/plugins directory, ADT features in the $ECLIPSE_HOME/dropins/adt/eclipse/features directory.

- restart Eclipse. 
- set Android AOSP using Window>Preferences>Android
- import attached HelloTabWidget project and open res/layout/main.xml.

2010年11月26日 星期五

Android, 幾種方式讓其他的執行緒去存取UI執行緒

Android 提供了幾種方式讓其他的執行緒去存取UI執行緒以便解決上述的問題:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler
  • AsyncTask

2010年11月20日 星期六

JUnit 4 in 60 Seconds

http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/

JUnit 4 in 60 Seconds

I played with JUnit 4 library this weekend and here is the short introduction to it:
  1. @TestMark your test cases with @Test annotations. You don’t need to prefix your test cases with “test”.  In addition, your class does not need to extend from “TestCase” class.
    1. @Test  
    2. public void addition() {  
    3.     assertEquals(12, simpleMath.add(75));  
    4. }  
    5.   
    6. @Test  
    7. public void subtraction() {  
    8.     assertEquals(9, simpleMath.substract(123));  
    9. }  
  2. @Before and @After
    Use @Before and @After annotations for “setup” and “tearDown” methods respectively. They run before and after every test case.
    1. @Before  
    2. public void runBeforeEveryTest() {  
    3.     simpleMath = new SimpleMath();  
    4. }  
    5.   
    6. @After  
    7. public void runAfterEveryTest() {  
    8.     simpleMath = null;  
    9. }  
  3. @BeforeClass and @AfterClassUse @BeforeClass and @AfterClass annotations for class wide “setup” and “tearDown” respectively. Think them as one time setup and tearDown. They run for one time before and after all test cases.
    1. @BeforeClass  
    2. public static void runBeforeClass() {  
    3.     // run for one time before all test cases  
    4. }  
    5.   
    6. @AfterClass  
    7. public static void runAfterClass() {  
    8.     // run for one time after all test cases  
    9. }  
  4. Exception Handling
    Use “expected” paramater with @Test annotation for test cases that expect exception. Write the class name of the exception that will be thrown.
    1. @Test(expected = ArithmeticException.class)  
    2. public void divisionWithException() {  
    3.     // divide by zero  
    4.     simpleMath.divide(10);  
    5. }  
  5. @Ignore
    Put @Ignore annotation for test cases you want to ignore. You can add a string parameter that defines the reason of ignorance if you want.
    1. @Ignore("Not Ready to Run")  
    2. @Test  
    3. public void multiplication() {  
    4.     assertEquals(15, simpleMath.multiply(35));  
    5. }  
  6. Timeout
    Define a timeout period in miliseconds with “timeout” parameter. The test fails when the timeout period exceeds.
    1. @Test(timeout = 1000)  
    2. public void infinity() {  
    3.     while (true)  
    4.         ;  
    5. }  
  7. New Assertions
    Compare arrays with new assertion methods. Two arrays are equal if they have the same length and each element is equal to the corresponding element in the other array; otherwise, they’re not.
    public static void assertEquals(Object[] expected, Object[] actual);
    public static void assertEquals(String message, Object[] expected, Object[] actual);
    1. @Test  
    2. public void listEquality() {  
    3.     List expected = new ArrayList();  
    4.     expected.add(5);  
    5.   
    6.     List actual = new ArrayList();  
    7.     actual.add(5);  
    8.   
    9.     assertEquals(expected, actual);  
    10. }  
  8. JUnit4Adapter
    Run your Junit 4 tests in Junit 3 test runners with Junit4Adapter.
    1. public static junit.framework.Test suite() {  
    2.     return new JUnit4TestAdapter(SimpleMathTest.class);  
    3. }  
Happy coding. :D

Android、JUnit深入浅出(三)—JUnit深入解析(下)

通過前面2篇文章的學習,我們對JUnit有了初步的認識,下面我們將深入的解析JUnit數據包。 整個JUnit的數據包應該是很強大的,但是一般來說,不一定每個工程都需要這些數據包,而是在JUnit部分數據包的基礎上擴展出自己的數據包,Android SDK中也不例外。 至於JUnit完整的包,這裡我們就不詳細分析了,我們這裡只解析Android SDK中包含的那些JUnit數據包,以及Android SDK在JUnit的基礎上擴展的一些數據包,如下:SDK功能說明


在這些包中最為重要的是:junit.framework、android.test,其中前者是JUnit的核心包,後者是Andoid SDK在Junit.framework的基礎上擴展出來的包,我們將重點解析這2個包。
首先解析junit.framework包,結構如下:





通過這張圖,大家就可以比較清晰的看到JUnit的主要框架,再回去看下上篇文章的例子,對前面的例子感覺明白多了。 做個簡要的總結,如下:
TestSuit:TestSuite是測試用例的集合;
TestCase:定義運行多個測試用例;
TestResult:收集一個測試案例的結果,測試結果分為失敗和錯誤,如果未能預計的斷言就是失敗,錯誤就像一個ArrayIndexOutOfBoundsException異常而導致的無法預料的問題;
TestFailure:測試失敗時捕獲的異常;
Assert:斷言的方法集,當斷言失敗時顯示信息;

TestCase與TestSuite之間的關係,有些類似於圖元對象與容器對象之間的關係,在面向對象的語言C++、JAVA中較常見,在這裡就不多說了。
舉個簡單的例子,並簡要說明過程

第一步:實現TestCase
繼承父類TestCase;
定義一下變量在測試中使用;
在setUp()中初始化這些變量;
在tearDown()中清理這些變量;
public class MathTest extends TestCase{
protected double fValue1;
protected double fValue2;
protected void setUp(){
fValue1= 2.0;
fValue2= 3.0;
}
}
編寫測試單元代碼;
public void testAdd() {
double result= fValue1 + fValue2;
assertTrue(result == 5.0);
}
運行測試用例,這裡有2種方法可以使用:
靜態類型:覆蓋runTes()和定義測試函數。 最常用的就是採用java的匿名類,如下:
TestCase test= new MathTest(”add”){
public void runTest() { testAdd();}
};
test.run();
動態類型:使用反射來實現runTest,它動態地發現並調用的方法,在這種情況下,測試案例的名字對應的測試方法來運行,如下:TestCase= new MathTest(”testAdd”);
test.run();

相比之下,第2種更符合面向對象的思維。

第二步:將TestCase添加到TestSuilt
TestSuite suite= new TestSuite();
suite.addTest(new MathTest("testAdd"));

由於TestSuite可以自動從TestCase中提取測試單元並運行,也可以用如下方法:
TestSuite suite= new TestSuite(MathTest.class);

一個測試用例就完成了,想要更加詳細的了解junit.framework,還是到Android SDK中仔細閱讀。
總結說明

看了這些代碼,再仔細看下JUnit的結構圖,是不是感覺更加清晰了,下一篇幅我們將深入解析android.test包。