詳解Android的四大應用程序組件
Android的一個核心特性就是一個應用程序可作為其他應用程序中的元素,可為其他應用程序提供數據。例如,如果程序需要用某些控件來加載一些圖片,另一個程序已經開發(fā)出了此項功能,且可供其他程序使用,就可以直接使用跨進程通信方式調用那個程序的功能,而不是自己再開發(fā)一個。為了實現這樣的功能,Android系統(tǒng)必須能夠在需要應用程序中的任何一部分時啟動它的進程,并且實例化那部分的Java對象。所以,不像大多數其他系統(tǒng)中的程序,Android程序不是只有單一的進入點,而是它們擁有系統(tǒng)實例化和運行必須的組件,Android中提供了4大組件;Android中的四大組件除了BroadcastReceiver之外,Activity、Service、ContentProvider都要必須在AndroidManifest.xml中注冊,而BroadcastReceiver可以在AndroidManifest.xml文件中注冊,也可以在Java代碼或者kotlin代碼中注冊;在Android 8.0后,在AndroidManifest.xml文件中靜態(tài)注冊廣播接收失效,是因為官方對耗電量的優(yōu)化,避免APP濫用廣播的一種處理方式。
1、Activity
Activty是一種展示型組件,Activity為用戶提供了一個可視的用戶界面。例如,一個撥打電話程序可能有一個Activity用來顯示可以撥打電話的聯系人,第二個Activity用來新建聯系人寫信息,其他的Activity用來查看具體的聯系人,或者更改聯系人信息,雖然應用程序中的各個Activity所提供的用戶界面聚合性很強,但是每個Activity都獨立于其他的Activity,每一個實例化的Activity都是Activity的子類,Intent可觸發(fā)了Activity的啟動,Intent可分為顯式Intent觸發(fā)和隱式Intent觸發(fā);顯式Intent觸發(fā)可明確的指向Activity組件,用如下代碼表示:
Intent in = new Intent(this,SecondActivity.class) MainActivity.this.startActivity(in)
隱式Intent觸發(fā)是指向一個或者2個以上的Activity的目標組件,它也可以沒有目標Activity,它的隱式觸發(fā)用如下代碼表示:
Intent intent = new Intent();
intent.setPackage("com.xe.launchmode");
intent.setAction("com.xe.actoin.MAP");
intent.addCategory("android.intent.category.APP_MAPS");
MainActivity.this.startActivity(intent);
2、Service
Service是一種后臺處理任務型組件,它一直在后臺運行,用于后臺處理一系列的計算任務或者處理其他事情的時候播放背景音樂等,每個service都擴展自Service類;Service組件和Activity組件的開啟是不同的,Activity只有一種啟動狀態(tài),用如下代碼表示:
Intent in = new Intent(this,SecondActivity.class) startActivity(in)
而Service的開啟卻有2種,當處于啟動狀態(tài)時,它可以做一些后臺任務,不需要和用戶界面交互,它的生命周期和應用程序一樣長,多媒體播放器播放音樂是應用Service的一個非常好的例子。多媒體播放器程序可能包含一個或者多個Activity,用戶通過這些Activity選擇并播放音樂。然而音樂回放并不需要一個Activity來處理,因為用戶可能會希望音樂一直播放下去,即使退出了播放器去執(zhí)行其他應用程序也不停止。為了讓音樂一直播放,多媒體播放器Activity可能會啟動一個Service在后臺播放音樂。Android系統(tǒng)會使音樂回放Service一直運行,即使在啟動這個Service的Activity退出之后。它的啟動可用如下代碼表示:
Intent in = new Intent(this,SecondActivity.class) MainActivity.this.startService(in)
當它處于綁定狀態(tài)時,它即可以做一些后臺任務,也可以和用戶界面做交互,它的生命周期和用戶界面一樣長,它的綁定可用如下代碼表示:
ServiceConnection mBinderPoolConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent = new Intent(mContext, MyService.class);
MainActivity.this.bindService(intent,new ServiceConnection(),Context.BIND_AUTO_CREATE);
以上2中開啟,不管是哪一種都不可以直接在Service中做耗時操作,因為它是運行在主線程中的,如果非要做耗時操作,應該開一個工作線程給它去執(zhí)行。
3、BroadcastReceiver
一般不執(zhí)行任何任務,僅僅是接收并相應廣播通知一類的組件。大部分廣播通知是由系統(tǒng)產生的,例如改變時區(qū)、鬧鐘提醒、用戶選擇了一幅圖片或者用戶改變了語言首選項。應用程序同樣也可以發(fā)送廣播通知,例如通知其他應用程序某些數據已經下載到設備上可以使用;一個應用程序的BroadcastReceiver來響應它的通知,所有的BroadcastReceiver的實現類都擴展自BroadcastReceiver類。BroadcastReceiver適合用于不同的組件以及不同的進程之間進行通信,它是沒有用戶界面的,是因為它在系統(tǒng)內部工作。下面介紹它的2種注冊方式,首先是靜態(tài)注冊,它是在AndroidManifest.xml文件中完成的,安裝應用時會被應用解析,不啟動應用也能接收廣播,用如下監(jiān)聽wifi狀態(tài)改變的代碼表示:
<receiver android:name=".myapplication.receiver.WifiReceiver"> <intent-filter> <action android:name="android.net.wifi.RSSI_CHANGED" /> <action android:name="android.net.wifi.STATE_CHANGE" /> <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> </intent-filter> </receiver>
從以上代碼可以發(fā)現,接收過程的匹配是通過<intent-filter>來描述的,可以總結出廣播是一個低耦合的觀察者模式這樣的結論。
另外一種方式就是動態(tài)注冊,需要啟動應用程序才可以接收到廣播,是通過在Java代碼中完成注冊的,用如下代碼表示它的動態(tài)注冊:
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
}
}
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("com.xe.intent.action.ACTION_1");
filter.addAction("com.xe.intent.action.ACTION_2");
SecondActivity.this.registerReceiver(receiver,filter);
發(fā)送廣播可用如下代碼來實現:
Intent intent = new Intent();
intent.setAction("com.xe.intent.action.ACTION_2");
MainActivity.this.sendBroadcast(intent);
以上2種廣播的注冊方式中廣播的接收是不可以做耗時操作的,因為接收廣播的方法是在主線程中被調用的。
4、ContentProvider
ContentProvider是一種共享數據型組件,應用程序可以通過ContentProvider來訪問其他應用程序的數據,包括其他應用程序的私有數據;和Service一樣,它是沒有用戶界面的,它的內部需要實現insert、update、delete和query方法,它在內部使用一份數據集合并且對數據集合沒有要求。ContentProvider是跨進程通信的,當Android系統(tǒng)收到一個需求某個組件進行處理的請求的時候,Android會確保處理此請求的組件的宿主進程是否已經在運行,如果沒有,則立即啟動這個進程。ContentProvider是提供一個外部接口ContentResolver給其他進程訪問數據的,下面一部分代碼簡單的表示query方法的使用過程:
Uri bookUri = Uri.parse("content://com.zyb.provider/data");
ContentResolver cr = ContentProviderActivity.this.getContentResolver();
Cursor bookCursor = cr.query(bookUri,new String[]{"_id","name"},null,null,null);
while (bookCursor.moveToNext()) {
int id = bookCursor.getInt(0);
String name = bookCursor.getString(1);
}
以上代碼,首先要創(chuàng)建要訪問數據的Uri,然后通過應用程序獲取ContentResolver接口,通過該接口獲取數據集合Cursor對象,最后通過Cursor對象查找索引獲取到最終所需的數據。好了,本章內容就寫到這里,由于本人技術有限,文章難免會出現錯誤,還望批評指正;后面我會找個時間寫一下Android四大組件工作過程的源碼分析,謝謝大家的閱讀。
以上就是詳解Android的應用程序組件的詳細內容,更多關于Android 應用程序組件的資料請關注腳本之家其它相關文章!
相關文章
android studio 3.6.1導入項目報錯提示無法下載classpath里的內容
這篇文章主要介紹了android studio 3.6.1導入項目報錯提示無法下載classpath里的內容,本文通過原因分析通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
android開發(fā) eclipse alt+”/”自動提示失效的解決方法
最近在學習android開發(fā)布局這塊。第一次學習,很多代碼不熟悉。所以自動提示對我來說很重要。但悲催的就是這個自動提示失效。今天在網上搜索了一下解決辦法,主要有一下幾種方法2014-05-05
Flutter Widget開發(fā)Shortcuts快捷鍵實例
這篇文章主要為大家介紹了Flutter Widget開發(fā)Shortcuts快捷鍵實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Android Studio導入Eclipse項目的兩種方法
本文主要介紹了Android Studio導入Eclipse項目的兩種方法。具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01
android開發(fā)環(huán)境中SDK文件夾下的所需內容詳解
在本篇文章里小編給大家整理的是關于android開發(fā)環(huán)境中SDK文件夾下的所需內容詳解,有興趣的朋友們參考學習下。2019-09-09

