客户端基础知识 | 青训营笔记

115 阅读5分钟

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

1. 什么是程序

开发者视角:

what 代码+资源 

why 改变世界 

how 知识

用户视角:

what 界面/互动/记忆 

why 工具/视频/游戏 

how:应用商店/搜索引擎/官网下载/三方引流

2. 安卓基础组件

1.1 界面组件: Activity & Fragment

what: Activity是界面容器

why: 前台交互 程序入口 布局容器

how: 

1.1.1 Activity

Example: 实现一个图片浏览器

① 实现一个图片浏览app(activity+fragment)

相机列表页(GridView+Adaptor)

相机图片页(GridView+Adaptor)

大图浏览页(ViewPage+Adaptor)

② 旋转屏幕场景(activity生命周期)

③ 内置升级能力(service使用)

④ 单一首页(single task)

⑤ 相关图片(single top)

⑥ 扫描所有图片(contentprovider)

⑦提供图片选择能力给系统(intent)

1.1.1.1 基本用法:

① activity 是声明在AndroidManifest.xml (注册)

.ui.Mainactivity 表明默认进入MainActivity

② 设置布局文件(activity_main.xml):

③ 绑定:

1.1.1.2 Activity 生命周期

- onCreate(): 创建时回调 一般在此处创建视图和绑定数据

- onStart(): 已启动,即将进入前台 (界面还是不可见的)

- onResume(): 与用户开始交互,位于activity栈顶

- onPause(): activity失去焦点或已暂停,activity界面部分可见,下一个生命周期是onResume()/onStop() 用户还是可见的

- onStop(): activity 不再可见 下一个回调是onRestart()或onDestroy()

- onRestart(): 重启已停止的activity 下一个回调是onStart()

- onDestory(): 销毁activity 释放该activity的所有资源

- onSaveInstanceState(): 在非正常关闭时回调,用于保存数据,不支持持久化数据

- onRestoreInstanceState()/ onCreate(): 用于恢复数据

△ 有的时候app退出不一定能走到onDestroy那一步

如果想记录用户使用时长:从onResume用户能看到界面开始记录,兼容安卓4.0需要在onPause记录,更高版本安卓可以在onstop结束计时

△ 配置改变也可以不重建activity

需要到AndroidManifest里配置Activity节点的configChange属性

比如:local(语言改变)/font/orientation(旋转屏幕)/keyboardHidden(键盘显示隐藏)时都可以不重建activity

△ 解决接电话crash问题

- 产生原因:页面回收导致本地变量被置空

- 解决:

添加判空逻辑或者

在onSaveInstanceState()写入要保存的数据,在onRestoreInstanceState()恢复数据

△ 在某个页面加入主页按钮

- 问题:点击页面当前页面栈加入新首页,返回后首页会消失

- 预期:点击首页按钮回到首页 上面的页面全部退出 (正常交互)

- 解决:将首页launchmode设置为singletask

1.1.1.3 Activity 启动模式

standard:默认模式 每次打开一个页面加入栈顶 页面允许重复

single Top:不允许连续重复(回调onNewIntent())

single Task:不允许同一个栈内重复 (回调onNewIntent())

single Instance:整个系统不允许重复

△ 每一个页面都得是activity嘛?

- 不一定嗷 可以是fragment

1.1.2 Fragment

设计activity是为了解决碎片化,速度快,可以方便界面分离

1.1.2.1 Fragment基本用法:

① 创建Fragment布局文件

② 创建Fragment子类,加载布局文件

③ activity加载fragment:

静态加载:布局中绑定

动态加载:fragmentmanager加载

1.1.2.2 生命周期
- onAttach() Fragment和Activity建立关联时调用

- onCreateView() 当fragment创建视图时调用

- onActivityCreated() activity的onCreate()方法已返回时调用

- onDestroyView() 当fragment中的视图被移除时调用

- onDetach: Fragment和activity取消关联时调用

1.2.2.3 与Activity交互

组件获取

1. Fragment获取activity中的组件:getActivity().findViewById(R.ID.XXX) [getActivity有可能为空得先绑定]

2. Activity获取fragment中的组件:getFragmentManger.findFragmentById(R.if.fragment_xxx)

数据传递

1. activity传输给fragment:setArguments(Bundle bundle)

2. Fragment传输给activity:

① 通过对象直接传递(方法调用/接口调用)

② 通过viewmodel/handler/broadcast/eventbus等通信

1.2 服务组件: Service

1.3.1 基本用法:

- 注册:AndroidManifest中使用<service .../>标签

- 创建:建立相应的service实现类

- 加载:startService()/bindService()

1.3.2 生命周期: 

- onStart():启动服务

- onBind()

- onCreate(): 进行初始化

- onDestroy()

1.3.3 与activity通信:

- 定义binder子类,并实现getService()方法,返回service对象

- 实现service类onBind()方法,返回上述binder对象

- 实例化serviceconnection对象,实现onServiceConnected()方法,从中获取到service实例

- activity 中调用bindService()方法,并传递步骤三ServiceConnection对象,将流程跑起来

- activity既可以通过调用service实例中的方法进行直接通信

1.3 广播组件: Broadcast

1.3.1 基本用法

静态广播:

- 注册:AndroidManifest中使用<receiver.../><intent-filter.../>

- 创建:建立相应的broadcastReceiver实现类

- 接收:在步骤2类onReceive()中接收广播

- 发送:context.sendBroadcast()

动态广播:

- 注册: Content.registerReceiver()

1.3.2 常用系统广播

Intent.Action_CONNECTIVITY_CHANGE

Intent.Action_BATTERY_CHANGED

Intent.Action_SCREEN_ON

Intent.Action_SCREEN_OFF

Intent.Action_PACKAGE_INSTALL

Intent.Action_BOOT_COMPLETED

Intent.Action_PACKAGE_ADDED

Intent.Action_PACKAGE_REPLACED/REMOVED

1.4 数据组件: ContentProvider & ContentResolver

(使用系统东西 eg: 系统图库 才会用)

1.4.1 基本用法

生产者:

- 注册:AndroidManifest中使用<provider .../>

  属性: authories/exported/readPermission/writePermission

- 创建: 建立相应的ContentProvider实现类

   方法: onCreate/getType/insert/delete/update/query

消费者:

- 声明:AndroidManifest中声明权限

- 使用:context.getContentResolver()

   方法:insert/delete/update/query

1.5 意图组件: Intent 

你想干什么事情 有什么需求 系统对这个需求进行处理

Context.startActivity(Intent)

Context. startService(Intent)

Context.sendBroadcast(Intent)

1.5.1 基本用法

显式intent:setComponent/setClass指定具体类

隐式intent:action(动作), data(数据), category(类别),type(数据类型),component(组件),extra(扩展信息),flag(标志位)

1.5.2 Intent (系统能力)

电话:Intent (Intent.ACTION_DIAL, Uri.parse("tel:10010"))

短信:Intent (Intent.ACTION_SENDTO, Uri.parse("smsto: 10010"))

使用:startActivity(intent)

3. 安卓通信组件

1. Handler 

处理主线程之间的通信

如果想对界面进行更新/界面属性 只能在主线程操作

主线程很宝贵qvq 耗时操作放在子线程

原理:消息队列

1.1 基本用法

- 创建:新建Handler,实现handleMessage(Message)

- 构造Message:what/setData()

- 发送:子线程调用Handler.sendMessage(Message) 发送Message

- 处理:在Handler的handleMessage(Message msg) 主线程更新UI

2. Binder

进程之间的通信:只需要一次内存交换

2.1 基本用法

服务端:

1. 定义一个AIDL文件

2. 实现描述的接口,编写service

3. 如果有实体类,需要提供实体类(jar包形式)

客户端:

1. 拿到AIDL文件

2. 绑定服务,获得接口持有对象

2.2 核心原理

匿名共享内存 Binder驱动 ServiceManager