实习笔记-3

在安卓中显示gif图片

使用WebView

1
2
3
4
5
6
<WebView
android:id="@+id/runWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
1
2
3
4
5
6
7
8
runWebView.loadDataWithBaseURL(null,
"<html>
<body bgcolor='#f3f3f3'>
<div align=center>
<IMG src='file:///android_asset/run.gif'/>
</div>
</body>
</html>", "text/html", "UTF-8",null);

实现底部状态栏

使用recyclerview + gridlayoutmanager

阅读更多

实习笔记-22

LiveData, MutableLiveData

防止暴露子类某些方法

1
2
val name: LiveData<NameBean> get() = _name
private val _name = MutableLiveData<NameBean>()

界面性能优化ViewStub

根据条件判断某些控件显示,某些不显示时,可以使用ViewStub来减少不必要的实例化开销。

android.view.ViewStub,ViewStub 是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有 ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候。

阅读更多

实习笔记-13

为什么用SurfaceView不用自定义组件

  • 小组件在布局上的局限性
    • 只支持原生控件,且不支持他们的后代
    • 难以动态更新动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FrameLayout
LinearLayout
RelativeLayout
GridLayout

AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
  • 只能显示在某一屏

优化空间

  • 壁纸的操作和部分launcher的操作冲突
  • 只能在右侧,对左撇子不友好
  • 两个wallpaper的drawFrame方法相似,可以进一步抽象
阅读更多

实习笔记-23

MutableLiveData踩坑

使用MutableLiveData的observer对数据进行观察,跳转界面返回后删除list中的元素,出现CurrentModificationException
改用Vector等线程安全的集合

Binder

Binder 与其他IPC的比较

binder 共享内存 Socket
拷贝一次 0 1
C/S模式,易用性高 控制负载,易用性差 C/S开销大
为每个App分配UID 访问接入点是开放的,不安全 访问接入点是开放的,不安全

共享内存 两个mmap,Binder一个mmap

阅读更多

实习笔记-16

Android View绘制流程

performTraversals()

获取Surface对象,performMeasure-丈量View树的各个view的大小,performLayout-对整个视图树进行布局,performDraw,对视图树进行绘制
源码解析

  1. 第一阶段,确定activity的宽高
1
2
3
4
5
6
7
8
9
if(Activity窗口是第一次被请求执行测量、布局和绘制操作){
if(如果窗口的类型是有状态栏的){
Activity窗口所需要的宽度和高度就是除了状态栏;
}else{
Activity窗口所需要的宽度和高度就是整个屏幕的宽高;
}
}else{
Activity窗口的宽高为frame成员变量中的保存的上一次测量、布局和绘制时的值;
}
阅读更多

实习笔记-15

gradle全局配置

配置GRADLE_USER_HOME环境变量

实习笔记-14

更新桌面小组件

  1. Handler更新:只能坚持几秒钟
  2. Service发送广播更新
    1. Service的context从onReceive获取,一切正常。会存在保活的问题,至少30分钟系统才调用onUpdate一次
    2. 使用lateinit保存onUpdate的context,会报错lateinit property mContext has not been initialized
  3. onUpdate暴力递归 点击后无法更新

实习笔记-25

创建型

单例

优点

  • 节省资源
    • 内存
    • 重对象中包含的io,文件指针
  • 调用方便

缺点

  • 适用于昂贵对象,对于轻量对象,为了维护单例造成的同步等开销比创建一个对象更高。得不偿失
  • 不方便mock,(可以把单例对象作为函数参数则可以mock),相较于静态方法更方便(静态方法需要代理的方式mock)
  • 测试时常常并行测试,使用单例会降低效率
    函数式编程,拷贝
    云控,打点 Alex
    静态工具方法,少用,不要有状态,确保永远不会变
阅读更多

实习笔记-24

设备到设备文件传输

如果您的应用以 Android 11 或更高版本为目标平台,您将无法使用 allowBackup 属性停用应用文件的设备到设备迁移。系统会自动启用此功能。

不过,即使您的应用以 Android 11 或更高版本为目标平台,您也可以通过将 allowBackup 属性设为 false 来停用应用文件的云端备份和恢复。

非 SDK 接口限制

相机

媒体 intent 操作需要系统默认相机
从 Android 11 开始,只有预装的系统相机应用可以响应以下 intent 操作:

阅读更多