Android?Intent詳解(最新推薦)
在Android開發(fā)中,Intent 是組件間通信的核心機(jī)制,用于在Activity、Service、BroadcastReceiver等組件之間傳遞消息、啟動(dòng)組件或共享數(shù)據(jù)。它相當(dāng)于一個(gè)“意圖”載體,描述了操作的目的、數(shù)據(jù)和附加信息,是Android組件解耦的關(guān)鍵。
一、Intent 核心作用
- 啟動(dòng)組件:啟動(dòng)Activity(
startActivity())、啟動(dòng)Service(startService()/bindService())、發(fā)送廣播(sendBroadcast())。 - 傳遞數(shù)據(jù):在組件間傳遞基本類型、對象、集合等數(shù)據(jù)。
- 指定操作:通過“動(dòng)作”“數(shù)據(jù)”等描述要執(zhí)行的操作(如“打開網(wǎng)頁”“發(fā)送郵件”),實(shí)現(xiàn)跨應(yīng)用交互。
二、Intent 類型
根據(jù)目標(biāo)組件的指定方式,Intent分為顯式Intent和隱式Intent,適用場景不同。
1. 顯式 Intent(Explicit Intent)
特點(diǎn):直接指定目標(biāo)組件的完整類名(ComponentName),明確告訴系統(tǒng)要啟動(dòng)哪個(gè)組件。
適用場景:啟動(dòng)應(yīng)用內(nèi)部組件(如本應(yīng)用的Activity、Service),因?yàn)殚_發(fā)者明確知道目標(biāo)組件的類名。
示例:啟動(dòng)應(yīng)用內(nèi)的SecondActivity
// Kotlin val intent = Intent(this, SecondActivity::class.java) startActivity(intent)
// Java Intent intent = new Intent(this, SecondActivity.class); startActivity(intent);
進(jìn)階:通過ComponentName指定
如需動(dòng)態(tài)指定組件(如跨進(jìn)程啟動(dòng)已知類名的組件),可通過ComponentName構(gòu)造:
val component = ComponentName(packageName, "com.example.app.SecondActivity") val intent = Intent().setComponent(component) startActivity(intent)
2. 隱式 Intent(Implicit Intent)
特點(diǎn):不直接指定目標(biāo)組件,而是通過“動(dòng)作(Action)”“類別(Category)”“數(shù)據(jù)(Data)”等描述操作意圖,由系統(tǒng)根據(jù)這些信息匹配最合適的組件(如系統(tǒng)瀏覽器、郵件應(yīng)用)。
適用場景:啟動(dòng)跨應(yīng)用組件(如調(diào)用系統(tǒng)瀏覽器打開網(wǎng)頁、調(diào)用相機(jī)拍照),無需知道目標(biāo)組件的類名。
示例:打開指定網(wǎng)頁(調(diào)用系統(tǒng)瀏覽器)
val intent = Intent(Intent.ACTION_VIEW) // 動(dòng)作:查看內(nèi)容
intent.data = Uri.parse("https://www.example.com") // 數(shù)據(jù):網(wǎng)頁地址
startActivity(intent)系統(tǒng)會匹配所有聲明了ACTION_VIEW且支持http協(xié)議的組件(通常是瀏覽器),并讓用戶選擇打開方式。
三、Intent 核心屬性
Intent通過一系列屬性描述操作意圖,核心屬性包括Action、Category、Data、Type、Extra、Flag等。
1. Action(動(dòng)作)
一個(gè)字符串,描述要執(zhí)行的操作(如“查看”“發(fā)送”“編輯”)。系統(tǒng)預(yù)定義了大量Action,也可自定義。
常用系統(tǒng)Action:
| Action常量 | 含義 | 適用場景 |
|---|---|---|
Intent.ACTION_VIEW | 查看數(shù)據(jù) | 打開網(wǎng)頁、圖片、文檔等 |
Intent.ACTION_SEND | 發(fā)送數(shù)據(jù) | 分享文本、圖片(調(diào)用分享面板) |
Intent.ACTION_CALL | 撥打電話 | 需要CALL_PHONE權(quán)限 |
Intent.ACTION_EDIT | 編輯數(shù)據(jù) | 編輯聯(lián)系人、圖片等 |
Intent.ACTION_MAIN | 應(yīng)用入口 | launcher啟動(dòng)應(yīng)用的主Activity |
自定義Action:
需使用全限定名(避免沖突),如com.example.app.ACTION_CUSTOM,用于應(yīng)用內(nèi)組件通信或跨應(yīng)用約定。
2. Category(類別)
對Action的補(bǔ)充,描述組件的額外特性(如“默認(rèn)組件”“ launcher入口”)。一個(gè)Intent可包含多個(gè)Category,系統(tǒng)會匹配所有聲明的類別。
常用系統(tǒng)Category:
Intent.CATEGORY_DEFAULT:默認(rèn)類別,隱式啟動(dòng)Activity時(shí)必須包含(否則匹配失敗)。Intent.CATEGORY_LAUNCHER:標(biāo)記應(yīng)用的主入口(與ACTION_MAIN配合,顯示在 launcher 上)。
示例:隱式啟動(dòng)時(shí)添加默認(rèn)類別
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.example.com")
intent.addCategory(Intent.CATEGORY_DEFAULT) // 必須添加,否則可能匹配失敗
startActivity(intent)3. Data 與 Type(數(shù)據(jù)與類型)
Data:通過Uri指定操作的數(shù)據(jù)(如content://contacts/people/1表示某個(gè)聯(lián)系人,http://example.com表示網(wǎng)頁)。Type:指定數(shù)據(jù)的MIME類型(如image/jpeg、text/plain),若Data已包含類型信息(如http對應(yīng)text/html),Type可省略。
注意:Data和Type會相互覆蓋,若需同時(shí)設(shè)置,需用setDataAndType()而非分別調(diào)用setData()和setType():
// 正確:同時(shí)設(shè)置Data和Type
intent.setDataAndType(Uri.parse("content://media/external/images/1"), "image/jpeg")
// 錯(cuò)誤:setType()會覆蓋Data的類型信息
intent.data = Uri.parse("content://media/external/images/1")
intent.type = "image/jpeg" // 此操作會清除data4. Extra(附加數(shù)據(jù))
鍵值對形式的附加數(shù)據(jù),用于在組件間傳遞數(shù)據(jù)(如傳遞用戶ID、文本內(nèi)容)。支持基本類型、數(shù)組、集合,以及實(shí)現(xiàn)Serializable或Parcelable的對象。
存儲與獲取數(shù)據(jù):
// 存儲數(shù)據(jù)
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("userId", 123) // 基本類型
intent.putExtra("username", "張三") // 字符串
intent.putExtra("isVip", true) // 布爾值
// 傳遞對象(需實(shí)現(xiàn)Parcelable或Serializable)
val user = User("張三", 20) // 假設(shè)User實(shí)現(xiàn)了Parcelable
intent.putExtra("user", user)
startActivity(intent)// 目標(biāo)組件中獲取數(shù)據(jù)
val userId = intent.getIntExtra("userId", -1) // 第二個(gè)參數(shù)為默認(rèn)值
val username = intent.getStringExtra("username") // 可為null
val isVip = intent.getBooleanExtra("isVip", false)
val user = intent.getParcelableExtra<User>("user") // 需指定泛型注意:
- 傳遞大量數(shù)據(jù)(如大圖片)可能導(dǎo)致
TransactionTooLargeException,建議用其他方式(如全局變量、文件)。 Parcelable比Serializable效率更高(Android推薦用Parcelable)。
5. Flag(標(biāo)記)
通過addFlags()設(shè)置,用于控制組件的啟動(dòng)模式、任務(wù)棧(Task)行為等。
常用Flag:
| Flag | 作用 |
|---|---|
Intent.FLAG_ACTIVITY_NEW_TASK | 啟動(dòng)新任務(wù)棧(常用于Service中啟動(dòng)Activity) |
Intent.FLAG_ACTIVITY_CLEAR_TOP | 若目標(biāo)Activity已在棧中,清除其上方所有Activity |
Intent.FLAG_ACTIVITY_SINGLE_TOP | 若目標(biāo)Activity在棧頂,則復(fù)用,不創(chuàng)建新實(shí)例 |
Intent.FLAG_GRANT_READ_URI_PERMISSION | 授予Uri的讀權(quán)限(跨應(yīng)用訪問文件時(shí)需用) |
示例:啟動(dòng)新任務(wù)棧中的Activity(如從Service啟動(dòng))
val intent = Intent(this, NotificationActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // 必須添加,否則Service中啟動(dòng)會崩潰 startActivity(intent)
四、Intent 過濾器(Intent Filter)
隱式Intent需要通過Intent過濾器匹配目標(biāo)組件。過濾器在AndroidManifest.xml中聲明,用于告訴系統(tǒng)“該組件能處理哪些Intent”。
一個(gè)組件可聲明多個(gè)過濾器,只要Intent匹配其中一個(gè)即可啟動(dòng)該組件。
過濾器匹配規(guī)則
Intent與過濾器的匹配需滿足3個(gè)條件(全部匹配):
- Action匹配:Intent的Action必須在過濾器的
action列表中(或過濾器無Action,Intent也無Action)。 - Category匹配:Intent的所有Category必須在過濾器的
category列表中(過濾器至少包含CATEGORY_DEFAULT,否則隱式啟動(dòng)失?。?。 - Data/Type匹配:Intent的Data/Type需與過濾器的
data規(guī)則匹配(如協(xié)議、MIME類型)。
示例:為Activity配置過濾器
聲明一個(gè)能處理“查看圖片”和“編輯圖片”的Activity:
<activity android:name=".ImageHandlerActivity">
<intent-filter>
<!-- Action:支持查看和編輯圖片 -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<!-- Category:必須包含默認(rèn)類別 -->
<category android:name="android.intent.category.DEFAULT" />
<!-- Data:支持圖片類型(image/*),協(xié)議不限 -->
<data android:mimeType="image/*" />
</intent-filter>
</activity>當(dāng)其他應(yīng)用發(fā)送包含ACTION_VIEW、CATEGORY_DEFAULT、image/jpeg類型的Intent時(shí),系統(tǒng)會將該Activity列為可選目標(biāo)。
五、特殊用法
1. 啟動(dòng)組件并獲取返回結(jié)果
通過Activity Result API(替代舊版startActivityForResult())啟動(dòng)Activity并獲取返回?cái)?shù)據(jù)。
示例:啟動(dòng)相機(jī)拍照并獲取照片
// 1. 注冊結(jié)果回調(diào)
val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
// 拍照成功,處理照片(photoUri為拍照后保存的路徑)
imageView.setImageURI(photoUri)
}
}
// 2. 啟動(dòng)相機(jī)(photoUri為提前創(chuàng)建的臨時(shí)文件路徑)
val photoUri = createTempPhotoUri() // 自定義方法:創(chuàng)建保存照片的Uri
takePictureLauncher.launch(photoUri)2. PendingIntent(延遲Intent)
一種特殊的Intent,用于在未來某個(gè)時(shí)刻由其他組件(如系統(tǒng)服務(wù))執(zhí)行。常用于通知(Notification)、鬧鐘(AlarmManager)、快捷方式等場景。
特點(diǎn):
- 包含觸發(fā)時(shí)的權(quán)限和上下文,即使創(chuàng)建它的應(yīng)用已退出,仍可正常執(zhí)行。
- 支持三種操作:啟動(dòng)Activity(
getActivity())、啟動(dòng)Service(getService())、發(fā)送廣播(getBroadcast())。
示例:通知中添加PendingIntent(點(diǎn)擊通知打開Activity)
// 創(chuàng)建打開DetailActivity的Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("id", 100)
// 創(chuàng)建PendingIntent(FLAG_IMMUTABLE:不可變,安全性更高)
val pendingIntent = PendingIntent.getActivity(
this,
0, // 請求碼(區(qū)分不同PendingIntent)
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
// 構(gòu)建通知
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("新消息")
.setContentText("點(diǎn)擊查看詳情")
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent) // 綁定PendingIntent
.build()
// 顯示通知
notificationManager.notify(NOTIFICATION_ID, notification)3. 發(fā)送廣播 Intent
通過sendBroadcast()發(fā)送廣播,由注冊了對應(yīng)過濾器的BroadcastReceiver接收。
示例:發(fā)送自定義廣播
// 發(fā)送廣播
val intent = Intent("com.example.app.ACTION_CUSTOM_BROADCAST")
// 限制廣播僅本應(yīng)用接收(Android 8.0+ 推薦)
intent.setPackage(packageName)
sendBroadcast(intent)<!-- 注冊廣播接收器(Manifest中) -->
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="com.example.app.ACTION_CUSTOM_BROADCAST" />
</intent-filter>
</receiver>
// 廣播接收器實(shí)現(xiàn)
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if ("com.example.app.ACTION_CUSTOM_BROADCAST" == intent.action) {
// 處理廣播
}
}
}
六、注意事項(xiàng)
隱式Intent的安全性:Android 10(API 29)后,隱式啟動(dòng)Activity需指定包名(setPackage())或通過resolveActivity()檢查是否有匹配組件,否則可能拋出異常:
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
if (intent.resolveActivity(packageManager) != null) { // 檢查是否有匹配組件
startActivity(intent)
} else {
// 提示用戶無可用應(yīng)用
}- 數(shù)據(jù)大小限制:Intent傳遞數(shù)據(jù)通過Binder機(jī)制,總大小限制約1MB,超過會導(dǎo)致
TransactionTooLargeException,建議用文件或跨進(jìn)程通信(IPC)替代。 - PendingIntent的 FLAG 選擇:Android 12(API 31)后,創(chuàng)建PendingIntent需指定
FLAG_IMMUTABLE或FLAG_MUTABLE:FLAG_IMMUTABLE:Intent不可修改(推薦,安全性高)。FLAG_MUTABLE:允許修改Intent(僅在需要?jiǎng)討B(tài)更新Intent時(shí)使用)。
總結(jié)
Intent 是Android組件通信的“橋梁”,通過顯式/隱式方式連接組件,支持?jǐn)?shù)據(jù)傳遞和操作描述。掌握其核心屬性(Action、Category、Data、Extra)、過濾器匹配規(guī)則,以及特殊用法(PendingIntent、Activity Result),是實(shí)現(xiàn)組件交互和跨應(yīng)用功能的基礎(chǔ)。合理使用Intent能大幅提升應(yīng)用的靈活性和擴(kuò)展性。
到此這篇關(guān)于Android Intent詳解(最新推薦)的文章就介紹到這了,更多相關(guān)Android Intent內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android Intent基礎(chǔ)用法及作用詳解
- Android面試Intent采用了什么設(shè)計(jì)模式解析
- Android使用Intent傳遞組件大數(shù)據(jù)
- android使用intent傳遞參數(shù)實(shí)現(xiàn)乘法計(jì)算
- Android使用Intent顯示實(shí)現(xiàn)頁面跳轉(zhuǎn)
- Android使用Intent隱式實(shí)現(xiàn)頁面跳轉(zhuǎn)
- Android Intent實(shí)現(xiàn)頁面跳轉(zhuǎn)的兩種方法
- Android Intent實(shí)現(xiàn)頁面跳轉(zhuǎn)的方法示例
相關(guān)文章
Android學(xué)習(xí)教程之圓形Menu菜單制作方法(1)
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)教程之圓形Menu菜單操作代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android中解決頁簽手指按下從左到右滑動(dòng)的bug
有一種方法可以阻止父層的View截獲touch事件,就是調(diào)用 getParent().requestDisallowInterceptTouchEvent(true);方法。這篇文章給大家介紹了Android中解決頁簽手指按下從左到右滑動(dòng)的bug,一起看看吧2016-10-10
Android retrofit上傳文件實(shí)例(包含頭像)
下面小編就為大家分享一篇Android retrofit上傳文件實(shí)例(包含頭像),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Android使用DisplayManager創(chuàng)建虛擬屏流程及原理解析
這篇文章主要介紹了Android使用DisplayManager創(chuàng)建虛擬屏流程及原理解析,DisplayManager提供了createVirtualDisplay接口,用于創(chuàng)建虛擬屏,虛擬屏可以把屏幕分出不同的區(qū)域,需要的朋友可以參考下2024-05-05
Android實(shí)現(xiàn)在線預(yù)覽office文檔的示例詳解
在移動(dòng)端展示在線 Office 文檔(如 Word、Excel、PPT)是一項(xiàng)常見需求,這篇文章為大家重點(diǎn)介紹了兩種方案的實(shí)現(xiàn)方法,希望對大家有一定的幫助2025-04-04
Android 出現(xiàn)問題Installation error: INSTALL_FAILED_CONFLICTING_P
這篇文章主要介紹了Android 出現(xiàn)問題Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12

