本文主要是介绍Android面试题汇总-Jetpack组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、Navigation
当然可以。Android Navigation组件是一个用于在Android应用中管理导航的框架,它简化了Fragment之间的交互和数据传递。
(1)Navigation组件的核心概念
- NavHostFragment: 作为容器,承载应用中的目的地(Destination)页面,即Fragment。
- NavController: 控制器,负责应用内的导航逻辑,如页面跳转、参数传递等。
- NavGraph: 导航图,定义了所有导航目的地和它们之间的关系。
- NavDestination: 目的地,代表应用中的一个页面,通常是Fragment。
- Navigator: 抽象类,定义了不同类型的导航行为,如FragmentNavigator、ActivityNavigator等。
(2)Navigation的工作流程
- 创建导航图 (NavGraph):
- 在
res
目录下创建一个navigation
资源目录。 - 导航图的根标签是
<navigation>
,其中startDestination
属性指定了默认显示的界面。 - 每个
<fragment>
标签代表一个Fragment类。 - 每个
<action>
标签代表导航操作,包括目的地、切换动画等信息。
- 在
- 添加NavHostFragment:
- 在Activity的布局中添加
<fragment>
标签,android:name
属性指定为NavHostFragment
。 app:navGraph
属性链接到前面创建的导航图资源文件。
- 在Activity的布局中添加
- 开始导航:
- 使用
Navigation.findNavController(View)
方法找到NavController
。 - 调用
navigate()
方法执行导航操作,可以传递参数。
- 使用
(3)参数传递和页面跳转
- 页面间的跳转通过 < action > 实现,支持两种参数传递方式:
- Bundle方式: 传统的Bundle传递参数。
- 安全参数 (SafeArgs): 使用插件生成的类和方法传递参数,提高类型安全性。
(4)动画
- 在
<action>
中配置动画,包括进场和退场动画。
(5)导航堆栈管理
- Navigation维护自己的任务栈,支持多种出栈操作:
- 系统返回键: 默认出栈操作,回退到上一个导航页面。
- popBackStack() 或 navigateUp(): 返回到上一个页面。
- popUpTo 和 popUpToInclusive: 设置跳转时出栈的行为,可以清理任务栈中的页面。
(6)DeepLink
- 支持通过
PendingIntent
或 URL链接直接定位到应用程序的某个destination。
(7)源码理解
- NavHostFragment 和 NavController 是Navigation组件的核心,负责解析导航图和管理导航堆栈。
- NavInflater 负责解析导航资源文件,生成 NavGraph。
- NavigatorProvider 存放所有 Navigator 的实例,负责具体的导航行为。
(8)自定义Navigator
- 可以自定义Navigator,例如自定义FragmentNavigator以解决Fragment重复创建的问题。
二、DataBinding
DataBinding是Android的一个库,它允许你绑定UI组件在布局文件中到数据源,这样可以更简单地编写代码来更新UI元素。
DataBinding的原理
-
APT预编译: 在编译时期,通过注解处理器(APT)生成绑定类,如
ActivityMainBinding
和ActivityMainBindingImpl
。 -
布局文件处理:
处理布局时,生成两个XML文件:
activity_main-layout.xml
:包含DataBinding所需的布局控件信息。activity_main.xml
:用于Android操作系统渲染的布局文件。
Model如何刷新View
- DataBindingUtil.setContentView: 此方法将XML中的各个View赋值给
ViewDataBinding
,完成findViewById
的任务。 - ViewModel层的notifyPropertyChanged: 当ViewModel层调用此方法时,
ViewDataBindingImpl
的executeBindings
方法中处理逻辑,从而更新UI。
View如何刷新Model
- 双向绑定:
ViewDataBindingImpl
的executeBindings
方法中为设置了双向绑定的控件添加监听器,如在EditText
上设置TextWatcher
。 - 监听器回调: 当数据发生变化时,
TextWatcher
的onTextChanged()
方法会通过回调更新Model。
DataBinding的使用
- 布局文件中的绑定: 在布局文件中,可以使用
<data>
标签来定义绑定的数据,并通过<variable>
标签来指定数据类型和变量名。 - 表达式语言: DataBinding支持表达式语言,允许在布局文件中直接写入逻辑代码,如条件语句、方法调用等。
- 资源引用: 可以在布局中直接引用资源文件,如字符串、颜色等。
- 事件绑定: 可以将事件处理器直接绑定到布局中的UI组件上。
DataBinding的优势
- 减少样板代码: 自动化的
findViewById
减少了初始化UI组件的代码。 - 提高性能: 相比传统的UI更新方式,DataBinding可以更高效地处理数据变化和UI更新。
- 类型安全: 编译时的类型检查减少了运行时错误。
- 维护性: 使得代码更加模块化,易于维护和测试。
DataBinding是MVVM架构中的关键组件,它通过声明性布局和绑定机制,提高了开发效率和应用性能。
三、ViewModel
(1)ViewModel的作用
- 数据存储和管理: ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。
- 生命周期意识: 它能够在配置更改(如屏幕旋转)时保留数据,避免重新创建Activity时丢失数据。
(2)ViewModel的创建和使用
- 创建: 通过
ViewModelProvider
获取ViewModel实例,例如:viewmodel = ViewModelProvider(this).get(MyViewModel::class.java)
。 - 数据共享: ViewModel可以在UI组件(如Activity与Fragment)间实现数据共享。
(3)ViewModel的生命周期
- ViewModel的生命周期通常比其所关联的Activity或Fragment更长。当Activity因为配置更改而被销毁并重新创建时,ViewModel仍然存在,因此可以继续使用之前保存的数据。
(4)ViewModel的内部工作原理
- ViewModelStore: 一个存储ViewModel实例的容器,使用HashMap来管理这些实例。
- Factory接口:
ViewModelProvider
的一个内部接口,用于构建ViewModel实例。
(5)ViewModel的优势
- 数据持久化: ViewModel可以在Activity的整个生命周期内多次调用
onCreate()
方法时持久保存UI数据。 - 避免内存泄漏: 引入ViewModel和LiveData后,可以实现ViewModel和View的解耦,避免内存泄漏和空指针异常。
(6)ViewModel的最佳实践
- 不持有View引用: ViewModel不应该持有View的引用,以避免内存泄漏。
- 使用LiveData: 结合LiveData使用,可以使ViewModel响应数据变化,并更新UI。
ViewModel通过这些机制提供了一个强大的数据管理和UI状态保持的解决方案,使得Android应用的开发更加高效和稳定。
ViewModel
类是 Android 架构中的关键组件之一。它充当业务逻辑或屏幕级别状态的持有者。其主要目的是将状态暴露给 UI,并封装相关的业务逻辑。其中一个关键优势是它缓存状态并在配置更改(例如屏幕旋转)时持久化状态。这意味着在不同 Activity 之间导航或处理配置更改时,UI 不需要重新获取数据。
(1)为什么使用 ViewModel?
- UI 状态持久化:ViewModel 允许您持久化 UI 状态。它确保数据在配置更改期间仍然可用。
- 访问业务逻辑:ViewModel 提供了方便的 API,用于数据持久化和访问业务逻辑。
(2)如何创建 ViewModel?
- 使用 ViewModelProviders.of():您可以使用以下代码创建 ViewModel:
MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
- 在 Activity 或 Fragment 中提供 ViewModelStore:每个 Activity 或 Fragment 都有一个 ViewModelStore 对象,用于保存该页面的 ViewModel 对象。
(3)为什么使用 ViewModel?
-
管理 UI 界面数据:ViewModel 可以帮助您管理 UI 界面的数据。它将加载数据与数据恢复从 Activity 或 Fragment 中解耦。
-
数据持久化:在 Android 系统中,需要数据恢复有两种场景:
- 场景1:资源相关的配置发生改变导致 Activity 被杀死并重新创建。
- 场景2:资源内存不足导致低优先级的 Activity 被杀死。
- 使用
onSaveInstanceState
和onRestoreInstanceState
可以处理部分数据的保存和恢复,但它只适合保存少量可以被序列化、反序列化的数据。 - 官方最终采用了
onRetainNonConfigurationInstance
的方式来恢复 ViewModel。在屏幕旋转时,通过 Binder 回调 Activity 的retainNonConfigurationInstances()
方法,数据保存在NonConfigurationInstances
对象中。再次使用时,从该对象中取出ViewModelStore
对象,其中保存了 ViewModel 集合。官方重写了onRetainNonConfigurationInstance
方法,在该方法中保存了ViewModelStore
。
-
Fragments 间共享数据:通过获取 Activity 的
ViewModelStore
对象,实现了 Fragment 之间的 ViewModel 共享。不同的 Fragment 可以共享同一份 ViewModel。因此,不同的 Fragment 可以使用相同的 Activity 对象来获取 ViewModel。
四、LiveData
什么是 LiveData
LiveData
是一个可被观察的数据容器类。它将数据包装起来,使得数据成为“被观察者”,而页面成为“观察者”。这样,当数据发生变化时,页面能够获得通知,进而更新 UI。
如何使用 LiveData
在页面中,我们可以通过 LiveData.observe()
方法对 LiveData 包装的数据进行观察。当我们想要修改 LiveData 包装的数据时,可以使用 LiveData.postValue()
或 LiveData.setValue()
。postValue()
在非 UI 线程中使用,而在 UI 线程中使用 setValue()
方法。
为什么使用 LiveData?
- 避免内存泄漏:观察者会绑定到 Lifecycle 对象,并在其关联的生命周期销毁后进行自我清理。
- 自动处理生命周期:如果观察者的生命周期处于非活跃状态(例如返回栈中的 Activity),则它不会接收任何 LiveData 事件
五、Lifecycle
在Android开发中,Lifecycle
是Jetpack组件库中的一个重要组件,它允许开发者以声明式方式管理应用组件(如Activity和Fragment)的生命周期。这样可以避免内存泄漏和其他常见的问题。
Lifecycle的概念与作用
Lifecycle
是一个生命周期感知型组件,它能够响应另一个组件(如Activity和Fragment)的生命周期状态的变化。其核心功能是将组件的生命周期状态通知给观察者(LifecycleObserver
),观察者根据这些状态变化来执行相应的操作。例如,在Activity或Fragment销毁时释放资源,在Activity或Fragment处于活跃状态时更新数据,在Activity或Fragment处于暂停状态时暂停某些操作。
Lifecycle的三大核心类
- LifecycleOwner: 是一个接口,表示具有生命周期的组件。Activity和Fragment都实现了这个接口。开发者可以通过实现这个接口来监听组件的生命周期变化。
- LifecycleRegistry: 是一个类,负责管理
LifecycleOwner
的生命周期状态,并将这些状态通知给已注册的观察者。 - LifecycleObserver: 是一个空方法接口,用于标识观察者,对
Lifecycle
对象进行监听。
Lifecycle的使用步骤
- 实现LifecycleOwner: 重写
getLifecycle
方法,返回一个LifecycleRegistry
实例。这个实例在不同的生命周期事件中通过markState
方法来标记状态。
class MyActivity : AppCompatActivity(), LifecycleOwner {private val mLifecycleRegistry = LifecycleRegistry(this)override fun getLifecycle(): Lifecycle {return mLifecycleRegistry}
}
- 继承LifecycleObserver: 创建一个类继承
LifecycleObserver
,并实现需要响应的生命周期事件方法。
class MyObserver : LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)fun onResumed(owner: LifecycleOwner) {// 你的代码逻辑}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)fun onPaused(owner: LifecycleOwner) {// 你的代码逻辑}
}
- 注册LifecycleObserver: 在
LifecycleOwner
中,使用getLifecycle().addObserver()
方法注册LifecycleObserver
。
class MyActivity : AppCompatActivity() {private val myObserver = MyObserver()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)lifecycle.addObserver(myObserver)}
}
通过以上步骤,你就可以使用Lifecycle
来管理你的应用组件的生命周期了。这样做可以让你的代码更加简洁,逻辑更清晰,同时也能提高应用的性能和稳定性。
这篇关于Android面试题汇总-Jetpack组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!