126.Intent详细讲解

126.Intent详细讲解

Intent:Android 组件间的“快递包裹”

首先,我们需要明确一个概念:Android 应用程序是由多个组件组成的,例如:

Activity: 负责用户交互的界面。Service: 在后台运行的任务,例如下载文件、播放音乐。Broadcast Receiver: 接收系统或应用程序发出的广播消息。Content Provider: 提供数据访问接口,允许其他应用程序访问你的数据。

这些组件就像一个个独立的模块,它们之间需要进行通信和协作才能完成复杂的任务。 而 Intent,就是负责在这些组件之间传递消息和数据的“快递包裹”。

Intent 的核心作用:

启动组件(“我要寄包裹!”)

Intent 可以用来启动一个 Activity、Service 或 Broadcast Receiver。这就像你告诉快递员:“我要寄一个包裹!”,快递员会根据你的指示,找到相应的收件人并送达。例如,你可以使用 Intent 启动一个新的 Activity 来显示用户个人资料,或者启动一个 Service 在后台下载文件。

传递数据(“包裹里有什么?”)

Intent 可以携带数据在组件之间传递。这就像你在快递包裹里放了一些东西(例如文件、照片、商品),收件人收到包裹后可以取出这些东西。例如,你可以使用 Intent 将用户名、密码等信息从一个 Activity 传递给另一个 Activity。

Intent 的两种类型:

显式 Intent(“指定收件人!”)

显式 Intent 明确指定了要启动的组件的类名(就像快递单上写明了收件人的姓名和地址)。

Android 系统会直接找到该组件并启动它。

使用场景: 通常用于启动应用程序内部的组件,例如启动同一个应用程序中的另一个 Activity。

示例:

val intent = Intent(this, MyActivity::class.java) // 明确指定要启动 MyActivity

startActivity(intent)

隐式 Intent(“告诉快递员需求!”)

隐式 Intent 没有明确指定要启动的组件的类名,而是指定了一组 action、category 和 data 等信息(就像你告诉快递员:“我要寄一个能打开网页的包裹!”)。

Android 系统会根据这些信息找到能够处理该 Intent 的组件(例如浏览器),并启动该组件。

使用场景: 通常用于启动其他应用程序的组件,例如打开网页、发送邮件、拨打电话等。

示例:

val intent = Intent(Intent.ACTION_VIEW) // 指定 action 为查看

intent.data = Uri.parse("http://www.example.com") // 指定要查看的数据是 URL

startActivity(intent) // 系统会找到能够打开网页的应用程序(例如浏览器)

Intent 的属性:

action(“包裹要做什么?”)

action 描述了 Intent 要执行的动作。例如:Intent.ACTION_VIEW(查看)、Intent.ACTION_SEND(发送)、Intent.ACTION_DIAL(拨打电话)等。

data(“包裹里的数据是什么?”)

data 指定了 Intent 要操作的数据。通常是一个 Uri 对象,表示数据的地址。例如:Uri.parse("http://www.example.com")(网页地址)、Uri.parse("tel:1234567890")(电话号码)等。

category(“包裹的分类?”)

category 提供了关于 Intent 的额外信息。例如:Intent.CATEGORY_LAUNCHER(表示该 Activity 可以在应用程序启动器中显示)。

extra(“包裹里的额外信息?”)

extra 用于携带额外的数据。可以使用 putExtra() 方法添加 extra 数据,使用 getStringExtra()、getIntExtra() 等方法获取 extra 数据。

使用 Intent 的步骤:

创建 Intent 对象(“准备快递包裹!”)

使用 Intent 的构造函数创建一个 Intent 对象。

设置 Intent 的属性(“填写快递单!”)

根据需要,设置 Intent 的 action、data、category 和 extra 等属性。

启动组件(“寄出快递包裹!”)

使用 startActivity()、startService() 或 sendBroadcast() 等方法启动相应的组件。

总结:

Intent 是 Android 组件之间进行通信和协作的关键机制。 它可以用来启动组件、传递数据,就像一个“快递包裹”一样,将消息和数据从一个地方送到另一个地方。

对于一个115的理论理解:

在WeatherActivity中:

weatherViewModel.locationLng = intent.getStringExtra("location_lng") ?: ""

val weatherViewModel by lazy { ViewModelProvider(this).get(WeatherShowViewModel::class.java) } 那这个是intent的一个构造函数吗?

不,val weatherViewModel by lazy { ViewModelProvider(this).get(WeatherShowViewModel::class.java) } 不是 Intent 的构造函数。 它是 Kotlin 中使用 ViewModelProvider 获取 ViewModel 实例的一种方式,并且使用了 lazy 委托来实现延迟初始化。

weatherViewModel.locationLng = intent.getStringExtra("location_lng") ?: "" 那使用intent不是先要构造intent吗,那为什么那个没有构造?

使用 intent.getStringExtra() 前提是已经有了一个 intent 对象。

在 weatherViewModel.locationLng = intent.getStringExtra("location_lng") ?: "" 这段代码中,我们没有看到显式地构造 Intent 对象。 这是因为这段代码通常出现在 Activity 的 onCreate() 方法或者 Fragment 的 onCreateView() 方法中,而启动该 Activity 或 Fragment 的 Intent 对象已经由 Android 系统创建并传递过来了。

从 PlaceSearchActivity 启动:

在 PlaceSearchActivity 中的 PlaceSearchAdapter 的 onCreateViewHolder 方法中,当用户点击一个地点时,会创建一个 Intent 对象,并将地点信息(经度、纬度、地点名称、地点地址)作为 extra 数据添加到 Intent 中,然后启动 WeatherActivity。

// PlaceSearchAdapter.kt

holder.itemView.setOnClickListener {

val position = holder.bindingAdapterPosition

val place = placeList[position]

val intent = Intent(placeSearchActivity,WeatherActivity::class.java).apply {

putExtra("location_lng", place.location.lng)

putExtra("location_lat", place.location.lat)

putExtra("place_name", place.name)

putExtra("place_address",place.address)

}

placeSearchActivity.viewModel.savePlace(place)

placeSearchActivity.startActivity(intent)

placeSearchActivity.finish()

}

在这个场景中,PlaceSearchActivity 是 Intent 对象的创建者和发送者,而 WeatherActivity 是 Intent 对象的接收者。

由系统启动(如果保存了地点信息):

在 PlaceSearchActivity 的 onCreate 方法中,会检查是否已经保存了地点信息(通过 viewModel.isPlaceSaved() 方法)。如果已经保存了地点信息,则会创建一个 Intent 对象,并将保存的地点信息作为 extra 数据添加到 Intent 中,然后启动 WeatherActivity。

// PlaceSearchActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_place_search)

val fromActivity = intent.getStringExtra("FROM_ACTIVITY")

if (fromActivity == null && viewModel.isPlaceSaved()) {

val place = viewModel.getSavedPlace()

val intent = Intent(this, WeatherActivity::class.java).apply {

putExtra("location_lng", place.location.lng)

putExtra("location_lat", place.location.lat)

putExtra("place_name", place.name)

putExtra("place_address",place.address)

}

startActivity(intent)

finish()

return

}

在这个场景中,PlaceSearchActivity 也是 Intent 对象的创建者和发送者,而 WeatherActivity 是 Intent 对象的接收者。这种情况通常发生在用户已经选择过地点,并且应用程序重新启动时。

从地点管理列表启动:

在 WeatherActivity 中的 PlaceManageAdapter 的 onCreateViewHolder 方法中,当用户点击一个地点管理列表中的地点时,会设置对应的经纬度等信息,然后调用refreshWeather()函数来更新天气,但没有直接创建新的intent,而是使用了已有的intent,并更新了相关信息。

holder.itemView.setOnClickListener {

val position = holder.bindingAdapterPosition

val placeManage = placeManageList[position]

weatherActivity.drawerLayout.closeDrawers()

weatherActivity.weatherViewModel.locationLng = placeManage.lng

weatherActivity.weatherViewModel.locationLat = placeManage.lat

weatherActivity.weatherViewModel.placeName = placeManage.name

weatherActivity.weatherViewModel.isUpdatePlaceManage = true

weatherActivity.refreshWeather()

val place = Place(placeManage.name, Location(placeManage.lng,placeManage.lat),placeManage.address)

weatherActivity.placeManageViewModel.savePlace(place)

}

总结:

WeatherActivity 可以被 PlaceSearchActivity 启动,或者由系统在应用程序重新启动时启动(如果保存了地点信息)。在这些场景中,Intent 对象由 PlaceSearchActivity 创建,并携带地点信息作为 extra 数据传递给 WeatherActivity。WeatherActivity 通过 getIntent() 方法获取 Intent 对象,并从中获取地点信息。

相关推荐

肯德基app怎么开发票
棋牌365大厅

肯德基app怎么开发票

📅 07-13 👁️ 7854
Wallpaper壁纸制作学习记录04
棋牌365大厅

Wallpaper壁纸制作学习记录04

📅 08-12 👁️ 3860
第15赛季季中:联动回归,劲弩铮鸣,混乱再起
microsoft 365下载

第15赛季季中:联动回归,劲弩铮鸣,混乱再起

📅 08-01 👁️ 6466
iPhone 12 & Pro 评测,除了环保还买了个啥?
日博365投注

iPhone 12 & Pro 评测,除了环保还买了个啥?

📅 07-01 👁️ 665