四大組件 Activity 實現步驟 繼承 Activity 或其子類,實現以下方法: //第一次創建時回調 protected void onCreate(Bundle savedInstanceState); //啟動時回調 protected void onStart(); //再次啟動時回調 ...
四大組件
Activity
實現步驟
-
繼承 Activity 或其子類,實現以下方法:
//第一次創建時回調 protected void onCreate(Bundle savedInstanceState); //啟動時回調 protected void onStart(); //再次啟動時回調 protected void onRestart() ; //回到前臺時回調 protected void onResume(); //轉入後臺但依然可見時回調 protected void onPause() ; //轉入後臺完全不可見時回調 protected void onStop(); //被系統銷毀時回調 protected void onDestroy();
-
在 AndroidMainfest.xml 文件中配置
-
啟動,有以下兩種方式:
//啟動其他Activity startActivity(Intent intent); //啟動其讓Activity並返回請求碼 startActivityForResult(Intent intent,int requestCode);
-
停止,有以下兩種方式:
//結束當前Activity finish(); //結束當前Activity並返回狀態碼 finish(Intent intent,int requestCode);
IBindle與Activity之間的通信
IBindle 是一個簡單的數據攜帶包,用於實現 Activity 之間的數據交換。Intent 提供了 putExtras() 和 getExtras() 方法,這些方法實質是存取 Intent 所攜帶的 IBindle 中的數據。
Intent 提供的多個重載方法攜帶額外數據:
//向Intent中存放數據包
putExtras(Bundle data);
//取出Intent中存放的數據包
getExtras(Bundle data);
//向Intent中以k-v形式存放數據包
putExtra(String name,String value);
//根據k取出指定類型的值
getXxxExtra(String name);
Bundle包含的多個方法來存入數據:
//向Bundle中存放數據
putXxx(String key,Xxx data);
//向Bundle中存放一個可序列化對象
putSerialzable(String key,Serialzable data);
生命周期
運行狀態:當前 Activity 位於前臺,用戶可見,可以獲得焦點;
暫停狀態:其他 Activity 位於前臺,該 Activity 依然可見,但無法獲得焦點;
停止狀態:該 Activity 不可見,無法獲得焦點;
銷毀狀態:該 Activity 結束或 Activity 所在進程被結束。
四種載入模式
standard:每次啟動目標 Activity 時,總會為目標 Activity 創建一個新實例,並添加到原有的 Task 中。
singleTop:當將要啟動的目標 Activity 位於 Task 棧頂中,系統直接服用已有的 Activity 實例。
singleTask:包括以下三種情況
- 啟動目標 Activity 不存在,創建新實例並加入到 Task 棧頂中;
- 啟動目標 Activity 存在且位於 Task 棧頂,直接復用已有 Activity 實例;
- 啟動目標 Activity 存在但不在 Task 棧頂,將位於目標 Activity 之上的實例移除 Task。
singleInstance:包括以下兩種情況:
- 啟動目標 Activity 不存在,先創建一個 Task,然後創建目標 Activity 實例並添加到 Task 中;
- 啟動目標 Activity 存在,將該 Activity 所在 Task 轉到前臺,使該 Activity 顯示出來。
ContentProvide
ContentProvide 是不同應用程式之間進行交換的標準 API,以某種 Uri 的形式對外提供數據,允許其他應用訪問或修改數據。
實現步驟
-
繼承 ContentProvider,實現以下方法:
//當其他程式第一次訪問該ContentProvider時,該ContentProvider被創建出來並立即回調onCreate() public boolean onCreate(); //根據Uri查詢selection條件所匹配的全部記錄,projection指的是列名列表,表明只選擇出指定的數據列 public Cursor query(Uri uri, String[] projection,String selection,String[] selectionArgs,String sortOrder); //用於返回當前Uri所代表的MIME類型 //若Uri對應數據包含多條記錄,該MIME類型字元串應以vnd.android.cursor.dir/開頭 //若Uri對應數據包含一條記錄,該MIME類型字元串應以vnd.android.cursor.item/開頭 public String getType(Uri uri); //根據Uri插入values對應的數據 public Uri insert(Uri uri, ContentValues values); //根據Uri刪除selection所匹配的全部記錄 public int delete(Uri uri, String selection,String[] selectionArgs); //根據Uri修改selection條件所匹配的全部記錄 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs);
-
向 AndroidMainfest.xml 文件中註冊該 ContentProvider,併為它綁定一個 Uri
Uri類似於互聯網中的URL,URL由協議、功能變數名稱、網站資源三個部分組成,Uri可以分為以下三部分
- Content://:暴露和訪問ContentProvider的協議預設為content://
- org.crazyit.providers.dictprovider:這部分是ContentProvider的authorities,用於指定要訪問的ContentProvider
- words:資源部分
Uri基本遵循了RESTful風格
ContentResolver
ContentProvider 相當於一個網站,它的作用是暴露可供操作的數據,其他程式則通過 ContentResolve r來操作 ContentProvider 所暴露的數據。ContentResolver 相當於 HttpClient.
Context 提供了以下方法來獲取 ContentResolver 對象:
//獲取應用的預設ContentResolver
getContentResolver();
//向Uri對應的ContentProvider
insert(Uri url,ContentValues values);
//刪除Uri對應的ContentProvider中where條件匹配數據
delete(Uri url,String where,String[] selectionArgs);
//更新Uri對應的ContentProvider中where條件匹配數據
update(Uri url,String where,String[] selectionArgs);
//查詢Uri對應的ContentProvider中where條件匹配數據
query(Uri url,String[] projection,String selection,String[] selectionArgs,String sortOrder)
ContentProvider 一般為單實例模式,多個程式通過 ContentResolver 操作 ContentProvider 提供數據時,會委托給同一個 ContentProvider
Uri 參數判斷
為了確定 ContentProvider 能夠處理 Uri,以及確定每個方法中 Uri 參數所操作的數據, Android 提供了 UriMatch、ContentUris 工具類。
UriMatcher 工具類
//向UriMatcher對象註冊Uri
void addURL(String authority,String path,int code);
//根據前面註冊的Uri來判斷Uri對應的標識,若無法匹配則返回-1
int match(Uri uri);
ContentUris 工具類
//用於為路徑添加ID部分
withAppendId(Uri contentUri, long id)
//用於指定Uri中解析出包含ID值
parseId(Uri contentUri);
系統的ContentProvider
Uri | 說明 |
---|---|
ContactsContract.Contacts.CONTENT_URL | 管理聯繫人的Uri |
ContactsContract.CommonDataKinds.Phone.CONTENT_URL | 管理聯繫人電話的Uri |
ContactsContract.CommonDataKinds.Email.CONTENT_URL | 管理聯繫人E-mail的Uri |
MediaStore.Audio.Media.EXTERNAL_CONTENT_URL | 存儲在手機外部存儲器上的音頻文件內容的Uri |
MediaStore.Audio.Media.INTERNAL_CONTENT_URL | 存儲在手機內部存儲器上的音頻文件內容的Uri |
MediaStore.Images.Media.EXTERNAL_CONTENT_URL | 存儲在手機外部存儲器上的圖片文件內容的Uri |
MediaStore.Video.Media.INTERNAL_CONTENT_URL | 存儲在手機內部存儲器上的視頻文件內容的Uri |
MediaStore.Video.Media.EXTERNAL_CONTENT_URL | 存儲在手機外部存儲器上的視頻文件內容的Uri |
Service
實現步驟
-
繼承 Service 重寫回調方法
-
在 Androidmainfest.xml 文件中配置該 Service
-
運行 Service,包括以下兩種方法:
- Context 的 startService() 方法,該方法啟動 Service 與啟動者不建立連接關係,啟動者退出 Service 保持運行。
- Centext 的 bindService() 方法,該方法啟動 Service 與啟動者綁定在一起,啟動者退出 Service 也退出。
//創建啟動Service的Intent Intent intent = new Intent(this, MusicService.class); //啟動後臺 startService(intent); //關閉後臺 stopService(intent);
創建顯式 Intents :
- 通過 Context、目標 Service 類創建顯式 Intent
- 通過package、action 屬性創建顯式 Intent
綁定本地 Service 並與之通信
當 Service 與訪問者 需要進行方法調用或交換數據時,應使用 bindService() 和 unbindService() 啟動和關閉 Service。
/**
* Service: 通過Intent指定需要啟動的Service
* Conn: 用於監聽訪問者與Service之間的連接情況.
* 訪問者與Service連接成功時將回調該ServiceConnection的onServiceConnected(ComponentName name,IBinder service)方法
* 訪問者與Service連接異常時將回調該ServiceConnection的onServiceDisconnected(ComponentName name,IBinder service)方法
* flags: 綁定時是否自動創建Service,參數可為0(不自動創建)或BIND_AUTO_CREATE(自動創建)
* */
public boolean bindService(Intent service, ServiceConnection conn,int flags);
ServiceConnection 對象的 onServiceConnected(ComponentName name,IBinder service) 有一個 IBind(Intent intent) 對象,該對象可實現與綁定 Service 之間的通信。
開發 Service 類時,該 Service 類必須提供一個 IBinder onBind(Intent intent) 方法。實際開發時通常會採用繼承 Binder 的方式實現 IBinder 對象。
生命周期
public class MusicService extends Service {
//被創建時回調
@Override
public void onCreate() {
super.onCreate();
}
//被綁定時回調
@Override
public IBinder onBind(Intent intent) {
return null;
}
//被啟動時回調
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
//被取消綁定時回調
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
//被停止時回調
@Override
public void onDestroy() {
super.onDestroy();
}
}
IntentService
Service 與它所在的應用位於同一進程中,因此不應該在 Service 中直接處理耗時操作。
IntentService 具有如下特征:
- IntentService 會創建獨立線程處理 onHandleIntent() 方法實現的代碼,開發者無需處理多線程問題。
- 當所有請求處理完成後,IntentService 會自動停止,因此無需調用 stopSelf() 方法來停止 Service。
- 為 Service 的 onBind() 方法提供了預設實現,預設返回為null.
- 為 Service 的 onStartCommand() 方法提供了預設實現,該實現會自動將請求 Intent 加入隊列中。
在使用擴展 IntentService 實現 Service 無須重寫 onBind()、onStartCommand() 方法,只要重寫 onHandleIntent() 方法即可。
BroadcastReceiver
broadcastReceiver 本質上是一個全局監聽器,用於監聽系統全局的廣播消息。
啟動步驟
-
創建需啟動的 BroadcastReceiver 的 Intent
-
調用 Context 的 sendBroadcast() 或 sendOrderBroadcast() 方法啟動指定的 BroadcastReceiver
//創建Intent Intent intent = new Intent(); //設置action屬性 intent.setAction("org.crazyit.action.CRAZY_BROADCAST"); intent.setPackage("org.crazyit.broadcast"); intent.putExtra("msg","簡單的消息"); //發送廣播 sendBroadcast(intent);
實現方式
-
繼承 BroadcastReceiver 重寫 onReceive(Context context, Intent inten) 方法
-
指定該 BroadcastReceiver 能匹配的 Intent,有以下兩種方式:
- 代碼中使用 BroadcastReceiver 的 Context 的 registerReceiver(BroadcastReceiver receiver,IntentFilter filter)
IntentFilter filter = new IntentFilter("android.provider.Telephoy.SMS_RECEIVED"); IncomingSMSReceiver receiver = new IncomingSMSReceiver(); registerReceiver(receiver ,filter);
- 在 AndroidMainfest.xml 文件中配置
<receiver android:name=".IncomingSMSReceiver"> <intent-filter> <action android:name = "android.provider.Telephony.SMS_RECEIVERD"/> </intent-filter> </receiver>
在實踐過程中,發現 Receiver 只有放在項目主目錄下才能被讀取註冊