android四大組件基礎介紹及打電話,發短信簡單應用 &單元測試

1,本章是android入門最後一篇,從後面開始將進入進階階段。我也會加快更新速度。但願能保持每天三篇博文的數量。但是是在保證質量的前提下。後面我還會發布一些實際開發中用到的應用案例。敬請關注!

應用組件是一個android應用程序的重要基石。每個組件的應用角度不同,各自負責所特有的功能。並非所有的組件都有實際的切入點,或許與別的組件相互依賴。但都作爲一個獨立的實體存在,起着特定的作用。有四種不同類型的應用組件。每種類型提供不同的用途,並各自擁有不同的生命週期。

所謂組件你可以這麼理解。一個汽車的構成一般有發動機,變速箱,底盤,車身,懸掛這幾部門組成。每一部分又都有獨立的作用。這和android中得組件類似。

下面是四種類型的應用程序組件:

Activity

字面意思活動,其實就表示與用戶交互的一塊單屏幕。比如說短信應用程序可能有一個活動,顯

示收發短信的列表,另一項活動,可以編寫短信。他們是不同的兩塊屏幕。一個Activity是單獨

的,它的關注點在於用戶能做什麼。幾乎所有的Activity都與用戶交互。在Android中一個程序 可

以訪問另一個程序中得某個Activity,這在其他語言程序中是不可想象的。極大的節省了系統資源。

所有的Activity必須在 AndroidManifest.xml.清單文件中註冊方可使用。

Service

服務是運行在後臺的一個組件,提到服務你可能首先想到的是windows中的服務。它在後臺默默

的爲你提供着你需要的功能。Android中得服務其實與windows中得服務類似,它執行長時間運

行的操作,或運程進程執行工作。服務不提供用戶界面,例如在後臺下載東西,播放音樂,在你

播放音樂的同時還可以幹其他事情,而不會阻塞用於與其他活動的交互。另一個組件,比如Activity

可以啓動一個服務,並運行或者綁定到它。

ContentProvider

內容提供者主要用於應用程序的數據共享設置,你可以把數據存儲在文件系統中,或者SQLite

據庫上,網絡,或者其他的持久性存儲位置。你可以訪問這些數據或者修改,其他應用程序也可

以訪問或者修改。(當然這需要內容提供商的允許)。最典型的例子就是android程序中得通訊錄

它就是通過內容提供者對外共享數據的。

BroadcastReceiver

廣播接收者,其實和我們生活中得廣播意思相近,在發生什麼事情的時候,會以廣播的形式告知

我們。廣播又分爲普通廣播和有序廣播。普通廣播是異步的,理論上是同時收到的。你不能對他

做任何操作,不能終止。有序廣播,在接收到廣播時可以加入自己的操作,傳遞給下一個接收者,

也可以終止廣播。 舉個例子 溫州動車追尾了,國家通過電視廣播的方式同時告知了我們。你沒

辦法終止它,或者改變它。這屬於普通廣播。有序廣播就是,比如張三的老婆郭美美在動車上,

國家通過電話通知張三:“你老婆很不幸在這次事故中喪生了”。張三可以在接到通知時終止它,

不告訴他丈母孃,也可以加入自己的操作,然後再告知丈母孃:“媽呀,美美在火車上出了點事,

在醫院呢。”當然有序廣播是有優先級的。國家打電話優先通知她老公。而不是她老母。這在後面

會詳細講解!Android系統中最常見的廣播電池電量低得時候,收到短信的時候,USB連接的時

候等等。

先暫時介紹一下四大組件,進階部分會有詳盡講解。多謝關注!下面來個簡單的例子作爲入門的結束!

先上圖:



<!--EndFragment-->

打電話的主要代碼:

Java代碼 複製代碼 收藏代碼
  1. mCall.setOnClickListener(new Button.OnClickListener(){
  2. @Override
  3. public void onClick(View v) {
  4. String phoneNumber=mPhoneNumber.getText().toString();
  5. //意圖 用於激活組件,綁定數據。充 當信使的作用
  6. Intent intent=new Intent();
  7. /*要執行的動作。執行不同的動作的Action去這找
  8. http://developer.android.com/reference/android/content/Intent.html */
  9. intent.setAction("android.intent.action.CALL");
  10. //綁定數據
  11. intent.setData(Uri.parse("tel:"+phoneNumber));
  12. //激活打電話組件 通過隱式意圖 另外不要忘記在清單文件中註冊一下打電話的權限
  13. startActivity(intent);
  14. }
  15. });
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mCall.setOnClickListener(new Button.OnClickListener(){  
  2.   
  3.      @Override  
  4.      public void onClick(View v) {  
  5.         String phoneNumber=mPhoneNumber.getText().toString();  
  6.         //意圖 用於激活組件,綁定數據。充 當信使的作用  
  7.         Intent intent=new Intent();  
  8.         /*要執行的動作。執行不同的動作的Action去這找 
  9.          http://developer.android.com/reference/android/content/Intent.html */  
  10.          intent.setAction("android.intent.action.CALL");  
  11.          //綁定數據  
  12.          intent.setData(Uri.parse("tel:"+phoneNumber));  
  13.           //激活打電話組件 通過隱式意圖 另外不要忘記在清單文件中註冊一下打電話的權限  
  14.          startActivity(intent);  
  15.         }  
  16.               
  17.         });  

發送短信的主要代碼:

Java代碼 複製代碼 收藏代碼
  1. mSendButton.setOnClickListener(new Button.OnClickListener(){
  2. @Override
  3. public void onClick(View v) {
  4. String phoneNumber=mPhoneNumber.getText().toString();
  5. String content=mMessage.getText().toString();
  6. //得到短信管理器
  7. SmsManager manager=SmsManager.getDefault();
  8. //如果短信內容超過70個字將被分割成多條
  9. ArrayList<String> messages=manager.divideMessage(content);
  10. //循環發送
  11. for(String ms:messages){
  12. //注:在模擬器中發送中文短信會亂碼 這跟底層的網絡有關。不過到真機上就沒事了。
  13. manager.sendTextMessage(phoneNumber, null, ms, nullnull);
  14. Toast.makeText(getApplicationContext(), "發送成功!"0).show();
  15. }
  16. }
  17. });
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mSendButton.setOnClickListener(new Button.OnClickListener(){  
  2.   
  3.     @Override  
  4.     public void onClick(View v) {  
  5.                 String phoneNumber=mPhoneNumber.getText().toString();  
  6.                  String content=mMessage.getText().toString();  
  7.         //得到短信管理器  
  8.         SmsManager manager=SmsManager.getDefault();  
  9.         //如果短信內容超過70個字將被分割成多條  
  10.         ArrayList<String> messages=manager.divideMessage(content);  
  11.         //循環發送  
  12.         for(String ms:messages){   
  13.         //注:在模擬器中發送中文短信會亂碼 這跟底層的網絡有關。不過到真機上就沒事了。  
  14.                 manager.sendTextMessage(phoneNumber, null, ms, nullnull);  
  15.             Toast.makeText(getApplicationContext(), "發送成功!"0).show();  
  16.             }  
  17.         }  
  18.               
  19.         });  

之所以還會在講這一點主要是 這是電話的最基本的兩個功能,還有一點在很多應用中還是會用到這些的,比如在CRM,OA,SNS應用上都有可能用上這個功能。最典型的在CRM上,在客戶資料上有電話號碼這一項,你可以直接加一按鈕就能撥打,總比再把號碼記下來用內置的撥打吧。

2,在實際開發中,開發android應用程序的過程中是需要不斷的進行單元測試的,使用JUnit測試框架,是正規android開發比用技術,良好的測試習慣,一是能減少後期維護 和增強軟件的健壯性。在JUnit中可以得到組件,可以模擬發送事件和檢測程序處理的正確性。

其實android中也是擴展了JUnit,派生出好幾個類傾向於不同情況下的測試。這一點與Spring中初始化容器相似,你可以通過BeanFactory 也可以通過ApplicationContext 來完成。只不過他們的傾向點不同。在android中你可以使用這些類來完成單元測試:

Test—TestCase—AndroidTestCase :多用於對業務邏輯的單元測試

Test—TestCase—InstrumentationTestCase :用於測試與組件交互的功能

Test—TestSuite—InstrumentationTestSuite :一組測試用例

TestListener——BaseTestRunner—AndroidTestRunner

InstrumentationInstrumentationTestRunner

我們常用到的一般是前前兩個,你會發現他們的基類都是Test。只不過各自的應用場景不同。

第一步:在AndroidManifest.xml中加入下面藍色代碼:

<!--EndFragment-->

Xml代碼 複製代碼 收藏代碼
  1. <application android:icon="@drawable/icon" android:label="@string/app_name">
  2. <!-- 使用的類庫 -->
  3. <SPAN style="COLOR: #0000ff"><uses-library android:name="android.test.runner"/></SPAN>
  4. <activity android:name="com.iteye.androidtoast.JUnitActivity"
  5. android:label="@string/app_name">
  6. <intent-filter>
  7. <action android:name="android.intent.action.MAIN" />
  8. <category android:name="android.intent.category.LAUNCHER" />
  9. </intent-filter>
  10. </activity>
  11. </application>
  12. <!-- 這裏的 targetPackage的內容與上面package內容需相同。表示該測試運行在此包下,說白了就是在同一個進程 -->
  13. <SPAN style="COLOR: #0000ff"><instrumentation android:name="android.test.InstrumentationTestRunner"
  14. android:targetPackage="com.iteye.androidtoast" android:label="Tests for My App" /></SPAN>
  1. <application android:icon="@drawable/icon" android:label="@string/app_name">  
  2.         <!-- 使用的類庫 -->  
  3.         <span style="color:#0000ff;"><uses-library android:name="android.test.runner"/></span>  
  4.         <activity android:name="com.iteye.androidtoast.JUnitActivity"  
  5.                   android:label="@string/app_name">  
  6.             <intent-filter>  
  7.                 <action android:name="android.intent.action.MAIN" />  
  8.                 <category android:name="android.intent.category.LAUNCHER" />  
  9.             </intent-filter>  
  10.         </activity>  
  11.   
  12.     </application>  
  13.     <!-- 這裏的 targetPackage的內容與上面package內容需相同。表示該測試運行在此包下,說白了就是在同一個進程 -->  
  14.     <span style="color:#0000ff;"><instrumentation android:name="android.test.InstrumentationTestRunner"  
  15.      android:targetPackage="com.iteye.androidtoast" android:label="Tests for My App" /></span>  

第二步,看代碼

首先是AndroidTestCase的簡單應用

Java代碼 複製代碼 收藏代碼
  1. package com.iteye.service.tests;
  2. import junit.framework.Assert;
  3. import android.test.AndroidTestCase;
  4. import android.util.Log;
  5. import com.iteye.service.SomeService;
  6. /**
  7. * 需要測試類要繼承AndroidTestCase
  8. * AndroidTestCase 多用於對系統中業務邏輯的測試
  9. * 需要與界面交互的測試一般採用InstrumentationTestCase
  10. * @author androidtoast
  11. *
  12. */
  13. public class SomeServiceTest extends AndroidTestCase {
  14. private static final String TAG="SomeServiceTest";
  15. SomeService some;
  16. protected int a;
  17. protected int b;
  18. //初始化測試環境 在實例化當前類的時候自動調用此方法
  19. @Override
  20. protected void setUp() throws Exception {
  21. super.setUp();
  22. some=new SomeService();
  23. a=3;
  24. b=8;
  25. }
  26. //測試結束後調用此方法,用於清理測試環境中得變量
  27. @Override
  28. protected void tearDown() throws Exception {
  29. super.tearDown();
  30. Log.i(TAG, "Test Over!");
  31. }
  32. //測試getAdd方法
  33. public void testAdd()throws Exception{
  34. Log.d(TAG, "testAdd");
  35. int result=some.getAdd(a, b);
  36. Assert.assertEquals(11, result);
  37. }
  38. }
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.iteye.service.tests;  
  2.   
  3. import junit.framework.Assert;  
  4. import android.test.AndroidTestCase;  
  5. import android.util.Log;  
  6.   
  7. import com.iteye.service.SomeService;  
  8. /** 
  9.  * 需要測試類要繼承AndroidTestCase 
  10.  * AndroidTestCase 多用於對系統中業務邏輯的測試 
  11.  * 需要與界面交互的測試一般採用InstrumentationTestCase 
  12.  * @author androidtoast 
  13.  * 
  14.  */  
  15. public class SomeServiceTest extends AndroidTestCase {  
  16.       
  17.     private static final String TAG="SomeServiceTest";  
  18.     SomeService some;  
  19.     protected int a;  
  20.     protected int b;  
  21.       
  22.     //初始化測試環境 在實例化當前類的時候自動調用此方法  
  23.     @Override  
  24.     protected void setUp() throws Exception {  
  25.             super.setUp();  
  26.             some=new SomeService();  
  27.             a=3;  
  28.             b=8;  
  29.     }  
  30.   
  31.     //測試結束後調用此方法,用於清理測試環境中得變量  
  32.     @Override  
  33.     protected void tearDown() throws Exception {  
  34.         super.tearDown();  
  35.         Log.i(TAG, "Test Over!");  
  36.     }  
  37.   
  38.     //測試getAdd方法  
  39.     public void testAdd()throws Exception{  
  40.         Log.d(TAG, "testAdd");  
  41.         int result=some.getAdd(a, b);  
  42.         Assert.assertEquals(11, result);  
  43.     }  
  44. }  

InstrumentationTestCase應用代碼:

Java代碼 複製代碼 收藏代碼
  1. package com.iteye.androidtoast.tests;
  2. import com.iteye.androidtoast.JUnitActivity;
  3. import com.iteye.androidtoast.R;
  4. import android.content.Intent;
  5. import android.os.SystemClock;
  6. import android.test.InstrumentationTestCase;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.TextView;
  10. /**
  11. * InstrumentationTestCase多用於測試與組件相關的操作
  12. * @author androidtoast
  13. *
  14. */
  15. public class JUnitActivityTest extends InstrumentationTestCase {
  16. JUnitActivity mActivityTested;
  17. public JUnitActivityTest() {
  18. }
  19. /**
  20. * 初始化測試環境
  21. */
  22. @Override
  23. protected void setUp() throws Exception {
  24. super.setUp();
  25. //意圖用於激活Activity
  26. Intent intent = new Intent();
  27. //設置用於激活哪個Activity
  28. intent.setClassName("com.iteye.androidtoast", JUnitActivity.class.getName());
  29. //啓動一個新的任務 並在後臺運行
  30. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  31. //獲得Instrumentation 啓動一個活動
  32. mActivityTested = (JUnitActivity) getInstrumentation().startActivitySync(intent);
  33. }
  34. //清理資源
  35. @Override
  36. protected void tearDown() throws Exception {
  37. mActivityTested.finish();//測試完成後關閉Activity
  38. super.tearDown();
  39. }
  40. //測試方法 (其實就是一個點擊按鈕 然後隱藏自身顯示文本這麼一簡單功能)
  41. public void testClickButtonToShowText() throws Exception {
  42. TextView tv = (TextView) mActivityTested.findViewById(R.id.text);
  43. SystemClock.sleep(2000);//等待兩秒
  44. //如果當前的TextView的狀態是隱藏的則正確通過
  45. assertEquals("TextView should be Gone before Button Clicking",
  46. View.GONE, tv.getVisibility());
  47. Button btn = (Button) mActivityTested.findViewById(R.id.button);
  48. //在主線程裏執行點擊按鈕這一動作
  49. getInstrumentation().runOnMainSync(new PerformClick(btn));
  50. SystemClock.sleep(2000);
  51. assertEquals("TextView should be Visible after Button Clicking",
  52. View.VISIBLE, tv.getVisibility());
  53. }
  54. private class PerformClick implements Runnable {
  55. Button mBtnClicked;
  56. public PerformClick(Button button) {
  57. mBtnClicked = button;
  58. }
  59. public void run() {
  60. mBtnClicked.performClick();
  61. }
  62. }
  63. }
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.iteye.androidtoast.tests;  
  2.   
  3. import com.iteye.androidtoast.JUnitActivity;  
  4. import com.iteye.androidtoast.R;  
  5.   
  6. import android.content.Intent;  
  7. import android.os.SystemClock;  
  8. import android.test.InstrumentationTestCase;  
  9. import android.view.View;  
  10. import android.widget.Button;  
  11. import android.widget.TextView;   
  12. /** 
  13.  * InstrumentationTestCase多用於測試與組件相關的操作 
  14.  * @author androidtoast 
  15.  * 
  16.  */  
  17. public class JUnitActivityTest extends InstrumentationTestCase {  
  18.   
  19.     JUnitActivity mActivityTested;  
  20.       
  21.     public JUnitActivityTest() {  
  22.     }  
  23.   
  24.     /** 
  25.      * 初始化測試環境 
  26.      */  
  27.     @Override  
  28.     protected void setUp() throws Exception {  
  29.         super.setUp();  
  30.         //意圖用於激活Activity  
  31.         Intent intent = new Intent();  
  32.         //設置用於激活哪個Activity  
  33.         intent.setClassName("com.iteye.androidtoast", JUnitActivity.class.getName());  
  34.         //啓動一個新的任務 並在後臺運行  
  35.         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  36.         //獲得Instrumentation 啓動一個活動  
  37.         mActivityTested = (JUnitActivity) getInstrumentation().startActivitySync(intent);  
  38.     }  
  39.   
  40.     //清理資源   
  41.     @Override  
  42.     protected void tearDown() throws Exception {  
  43.         mActivityTested.finish();//測試完成後關閉Activity  
  44.         super.tearDown();  
  45.     }  
  46.     //測試方法 (其實就是一個點擊按鈕 然後隱藏自身顯示文本這麼一簡單功能)  
  47.     public void testClickButtonToShowText() throws Exception {  
  48.         TextView tv = (TextView) mActivityTested.findViewById(R.id.text);  
  49.         SystemClock.sleep(2000);//等待兩秒  
  50.         //如果當前的TextView的狀態是隱藏的則正確通過  
  51.         assertEquals("TextView should be Gone before Button Clicking",  
  52.                 View.GONE, tv.getVisibility());  
  53.           
  54.         Button btn = (Button) mActivityTested.findViewById(R.id.button);  
  55.         //在主線程裏執行點擊按鈕這一動作  
  56.         getInstrumentation().runOnMainSync(new PerformClick(btn));  
  57.         SystemClock.sleep(2000);  
  58.         assertEquals("TextView should be Visible after Button Clicking",  
  59.                 View.VISIBLE, tv.getVisibility());        
  60.     }  
  61.       
  62.     private class PerformClick implements Runnable {  
  63.         Button mBtnClicked;  
  64.           
  65.         public PerformClick(Button button) {  
  66.             mBtnClicked = button;  
  67.         }  
  68.           
  69.         public void run() {  
  70.             mBtnClicked.performClick();  
  71.         }  
  72.     }  
  73.   
  74. }  

  • 大小: 44.8 KB
  • 大小: 46.3 KB
  • SMS.rar (417.4 KB)
  • 下載次數: 1000

 

http://androidtoast.iteye.com/blog/1169635
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章