【2022暑假】二、客户端基础知识必备 | 青训营笔记

169 阅读8分钟

这是我参与「第四届青训营 」笔记创作活动的第2天。

读前须知:我是安卓方向零基础的新手,这个系列的笔记将主要用于记载我认为重要的知识点,不一定适用于所有人的学习情况。虽是新手但我依旧会尽力避免出现错误,不过如果没能完全避免,还希望读者能不惜笔墨地指出。

一、本堂课重点内容:

  1. 安卓系统基础组件介绍

二、详细知识点介绍:

  1. 安卓系统基础组件介绍

    1. 界面组件Activity和Fragment

      • Activity的作用

        Activity的是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务。Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)显示指定控件。在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。

      • Activity的基本用法

        Activity都必须要在AndroidManifest.xml配置文件里注册,并且必须适当地管理 Activity 的生命周期。

      • Activity的生命周期

        Activity的回调九个回调函数。在使用Activity的过程中可以不用实现所有的回调方法。

        • onCreate(): 创建时回调,一般在此处创建视图和绑定数据
        • onStart(): 已启动,即将进入前台
        • onResume(): 与用户开始交互,位于Activity栈顶
        • onPause(): Actvity失去焦点或已暂停,Activity界面部分可见,下一个生命周期是onResume()onStop()
        • onStop(): Activity不再可见,下一个回调是onRestart()onDestory()
        • onRestart():重启已停止的Activity,下一个回调是onStart()
        • onDestory(): 销毁Actvity,释放该Activity的所有资源
        • onSaveInstanceState(): 在非正常关闭时回调,用于保存数据,不支持持久化数据
        • onRestoreInstanceState() / onCreate(): 用于恢复数据

        Activity在生命周期里拥有四种基本状态:

        1. Active/Running 一个新 Activity 启动入栈后,它显示在屏幕最前端,处理是处于栈的最顶端(Activity栈顶),此时它处于可见并可和用户交互的激活状态

        2. Paused Activity失去焦点,或者说一个新的Activity没有完全覆盖掉旧的Activity,此时它仍然可见,但已经失去了焦点故不可与用户进行交互。

        3. Stopped 如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(Stopped)。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,Stopped的Activity将被强行终止掉。

        4. Killed 如果一个Activity是Paused或者Stopped状态,系统可以将该Activity从内存中删除。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。

        回调函数在状态转移中所处的位置如图所示:

        Snipaste_2022-07-31_14-43-03.png

      • Activity的四种启动模式

        1. standard:默认的启动方式。在该模式中,每启动一个新活动,都会创建一个新的实例,并在任务栈中入栈,处于栈顶的位置。假设你不停地进入同一个活动,你点击了十次,就要返回十次才能退出程序,因为你在返回栈中创造了十个相同的实例,尽管活动是一样的。

        2. singleTop:启动一个新活动时,系统会检查该活动是否已经位于任务栈栈顶,如果是的话直接使用已存在的栈顶活动,否则就创建新活动并压入栈顶。

        3. singleTask:和 singleTop 类似,不过这里是检查整个任务栈的活动,如果发现已经存在该活动就将位于该活动上方的活动全部出栈,该活动成为新的栈顶。

        4. singleInstance:最特殊的模式,系统为该模式的活动分配一个独立的任务栈,该任务栈有且只有一个该活动实例。也就是说,如果已经创建过目标活动实例,那么将不会创建新的任务栈,而是唤醒之前创建过的活动实例。

      • Fragment与Activity的关系

        Fragment能将界面划分为离散的区块,从而将模块化和可重用性引入 Activity 的界面。Activity 是围绕应用的界面放置全局元素(如抽屉式导航栏)的理想位置。相反,Fragment 更适合定义和管理单个屏幕或部分屏幕的界面。

        假设有一个响应各种屏幕尺寸的应用。在较大的屏幕上,该应用应显示一个静态抽屉式导航栏和一个采用网格布局的列表。在较小的屏幕上,该应用应显示一个底部导航栏和一个采用线性布局的列表。在 Activity 中管理所有这些变化因素可能会很麻烦。将导航元素与内容分离可使此过程更易于管理。然后,Activity 负责显示正确的导航界面,而 Fragment 采用适当的布局显示列表。

        Snipaste_2022-07-31_14-43-03.png

      • Fragment的基本用法

        1. 创建Fragment布局文件
        2. 创建Fragment子类,加载布局文件
        3. Activity加载Fragment
          3.1 静态加载:布局中绑定
          3.2 动态加载:FragmentManager加载
      • Fragment的生命周期

        五个回调函数:

        • onAttach() Fragment和Activity建立关联时调用
        • onCreateView() 当Fragment创建视图时调用
        • onActivityCreated() Activity的onCreate()方法已返回时调用
        • onDestroyView() 当Fragment中的视图被移除时调用
        • onDetach() Fragment和Activity取消关联时调用

        Fragment与Activity生命周期的关系:

        image.png

      • Fragment与Activity的交互

        组件获取:

        1. Fragment获取Activity中的组件: getActivity().findViewByld(R.id.xxx)
        2. Activity获取Fragment中的组件: getFragmentManager.findFragmentByld(R.id.fragment_xox)

        数据传递:

        1. Activity传数据给Fragment: setArguments(Bundle bundle)
        2. Fragment传数据给Activity:
          1. 通过对象直接传递(方法调用/接口调用)
          2. 通过viewmodel / handler / broadcast / eventbus等通信
    2. 服务组件Service

      • 基本用法

        1. 注册: AndroidManifest.xml中使用<service.../>标签
        2. 创建: 建立相应的Service实现类
        3. 加载: startService() / bindService()
      • 生命周期

        回调函数:

        • onCreate(): 创建
        • onStartCommand(): 开始
        • onDestroy(): 销毁
        • onBind(): 绑定
        • onUnbind(): 解绑

        和生命周期的关系如图:

        image.png

      • Service和Activity的交互

        1. 定义Binder子类,并实现getService()方法,返回Service对象
        2. 实现Service类onBind()方法,返回上述Binder对象
        3. 实例化ServiceConnection对象,实现onServiceConnected()方法,从中获取到Service实例
        4. Activity中调用bindService()方法,并传递步骤3的ServiceConnection对象,将流程跑起来
        5. Activity既可以通过调用Service实例中的方法进行直接通信,也可以通过broadcast(广播)的形式通信
    3. 广播组件Broadcast

      • 基本用法

        静态广播

        1. 注册: AndroidManifest中使用<receiver../> <intent-filter.../>
        2. 创建: 建立相应的BroadcastReceiver实现类
        3. 接收: 在步骤2类onReceive()中接收广播
        4. 发送: Context.sendBroadcast()

        动态广播

        1. 注册: 在需要的地方使用registerReceiver()unregisterReceiver()
        2. 创建: 声明一个ACTION
        3. 接收与发送都和静态广播一致
      • 作用范围

        静态广播:整个App的生命周期 动态广播:注册和注销期间

    4. 数据组件ContentProvider和ContentResolver

      • 基本用法

        生产者

        1. 注册: AndroidManifest中使用<provider.../> 属性: authorities / exported / readPermission / writePermission
        2. 创建: 建立相应的ContentProvider实现类 方法: onCreate / getType / insert / delete / update / query

        消费者

        1. 声明: AndroidManifest中声明权限
        2. 使用: context.getContentResolver()方法: insert / delete / update / query
    5. 意图组件Intent

      • Intent的作用

        Android意图是一个要执行的操作的抽象描述。它可以通过 startActivity 来启动一个活动,broadcastIntent 来发送广播到任何对它感兴趣的广播接受器组件,startService(Intent) 或者bindService(Intent, ServiceConnection, int) 来与后台服务通讯。意图本身(一个 Intent 对象)是一个被动的数据结构,保存着要执行操作的抽象描述。

      • 显式Intent

        显式意图用于连接应用程序的内部世界,假设你需要连接一个活动到另外一个活动,我们可以通过显示意图。这些意图通过名称指定目标组件,一般用于应用程序内部信息 - 比如一个活动启动一个下属活动或者启动一个兄弟活动。

        // 通过指定类名的显式意图
        Intent i = new Intent(FirstActivity.this, SecondAcitivity.class);
        
        // 启动目标活动
        startActivity(i);
        
      • 隐式Intent

        相比于显式Intent,隐式Intent则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的 action和 category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。 通过在AndroidManifest.xml中<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够响应的Action(动作)、Data(数据)、Category(类别)、Type(数据类型)、Component(组件)、Extra(扩展信息)、Flag(标志位)。

三、实践练习例子:

  1. 建议复现一下《第一行代码》中关于生命周期的例子、或网络上讲述生命周期的代码样例,之后对各个组件生命周期的理解会更加清晰。

四、课后个人总结:

  • 本章介绍的各个基础组件的内容比较多,需要细心掌握。

  • 各个组件的生命周期和回调函数容易弄混,需要仔细辨别。

五、引用参考:

  1. Activity 简介
  2. Android 活动(Activity)
  3. Activity 的启动:四种启动模式及各种 FLAG
  4. Fragment
  5. Fragment lifecycle
  6. Fragment生命周期
  7. 详解Android Service与Activity之间通信的几种方式
  8. Android BroadcastReceiver 广播接收者基本用法