就算不去火星种土豆,也请务必掌握的 Android 状态管理最佳实践!

}

直到 2017 年的夏天,我在和一位彼时 3 年经验的同事,联手完成当年扛鼎项目的核心功能时,因同事提出使用十六进制管理状态,而亲眼见证了十六进制在状态管理方面的绝佳优势。

为了纪念同事的这一分享,此后每当有新同事入职,我提供的培训课程必包含十六进制状态管理。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用十六进制前的混沌世界

该项目有个需求:当指定图形编辑的模式时,图形工具栏的按钮状态要随之发生配套性地变化。

例如,存在 3 种图形编辑模式,和 8 个图形编辑按钮。

模式 A 下,要求 按钮1、按钮2、按钮3 可用,其他按钮禁用。

模式 B 下,要求 按钮1、按钮4、按钮5、按钮6 可用,其他按钮禁用。

模式 C 下,要求 按钮1、按钮7、按钮8 可用,其他按钮禁用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果是传统方式编写,我们势必会在类中为 3 个模式定义 boolean 变量,为 8 个按钮状态定义 boolean 变量。

那么在模式切换时,就需要将每个按钮状态的变量都 “清洗” 一遍。例如:

public void setModeA() {
status1 = true;
status2 = true;
status3 = true;
status4 = false;
status5 = false;
status6 = false;
status7 = false;
status8 = false;
}

public void setModeB() {
status1 = true;
status2 = false;
status3 = false;
status4 = true;
status5 = true;
status6 = true;
status7 = false;
status8 = false;
}

public void setModeC() {

}

那要是日后模式变多、按钮状态变多,类中就会满是这种 setMode 的方法,看起来很蠢,而且密密麻麻的 true、false,极容易出错。

这是一点。

另一点就是,如果按钮状态是用 boolean 变量来管理,那么状态的存储和读取怎么办呢?

  • 每个 boolean 变量都要转换成 int 类型的 0 或 1 存储在数据库中。
  • 数据库需要为每个状态准备一个字段。
  • 读取的时候又要负责将每个状态转译回 boolean。

这工作量也太大了!而且日后每添加或修改一个状态,数据库都要新增或修改字段,这非常低效和不安全!

十六进制能很好地解决这些问题

十六进制可以做到:

  • 通过状态集的注入,一行代码即可完成模式的切换。
  • 无论再多的状态,都只需要一个字段来存储。状态被存放在 int 类型的状态集中,可以直接向数据库写入或读取。

十六进制的运作机制

在具体了解十六进制是怎么做到状态管理最佳实践之前,我们先简单过一遍十六进制本身的运作机制。

首先,在编程中,利用开头 0x 表示十六进制数。

例如 0x0001,0x0002。

然后,十六进制的计算,我们可以借助二进制的 “按位计算” 方式来理解。

二进制存在 与、或、异或、取反 等操作:

a & b,a | b,a ^ b,~a

例如,十六进制数 0x0004 | 0x0008,可以理解为:

0100
|
1000

1100

十六进制 (0x0004 | 0x0008) & 0x0004 可以得到:

1100
&
0100

0100

也即状态集中包含某状态时,再与上该状态,就会得到非 0 的结果。

于是,我们就可以利用这个特性来完成状态管理:

十六进制的状态管理实战

  • 首先我们定义一个状态集变量,用来存放当前模式的状态集,例如:

private int STATUSES;

  • 然后我们定义十六进制状态常量,和模式状态集,例如:

private final int STATUS_1 = 0x0001;
private final int STATUS_2 = 0x0002;
private final int STATUS_3 = 0x0004;
private final int STATUS_4 = 0x0008;
private final int STATUS_5 = 0x0010;
private final int STATUS_6 = 0x0020;
private final int STATUS_7 = 0x0040;
private final int STATUS_8 = 0x0080;

private final int MODE_A = STATUS_1 | STATUS_2 | STATUS_3;
private final int MODE_B = STATUS_1 | STATUS_4 | STATUS_5 | STATUS_6;
private final int MODE_C = STATUS_1 | STATUS_7 | STATUS_8;

  • 当我们需要往状态集中添加状态时,就通过或运算。例如:

STATUSES | STATUS_1

  • 当我们需要从状态集中移除状态时,就通过取反运算。例如:

STATUSES & ~ STATUS_1

  • 当我们需要判断状态集中是否包含某状态时,就通过与运算。结果为 0 即代表无,反之有。

public static boolean isStatusEnabled(int statuses, int status) {
return (statuses & status) != 0;
}

  • 当我们需要切换模式时,我们可以直接将预先定义好的 “模式状态集” 赋予给状态集变量。例如:

STATUSES = MODE_A;

如此,复杂度从 m * n 骤减为 m + n,随着日后模式和状态的增多,十六进制的优势将指数级增长!

是不是超简洁?再也不需要定义和修改各种 “setModeXXX” 方法了。

而且这还只是一半。另一半是关于十六进制状态的存取。

十六进制的状态存取实战

由于状态集是 int 类型,因而我们最少只需一个字段,即可存储状态集:

insert into tableXXX TITLE,DATE,STATUS values (‘xxx’,‘20190703’,32)

读取也十分简单,读取后直接赋值给 STATUSES 即可。

除此之外,你还可以直接在 SQL 中通过按位计算来查询!例如查询包含状态 0x0004 的记录:

select * from tableXXX where STATUS & 4 != 0

综上

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

总之啊,家里没矿的同学们,如果你们想以后的日子过得好一些,多想想你们的业余时间怎么安排吧;

技术方面的提升肯定是重中之重,但是技术外的一些“软实力”也不能完全忽视,很多时候升职确实是因为你的技术足够强,但也与你的“软实力”密切相关

在这我也分享一份大佬自己收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅并给下属员工学习的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

相信自己,没有做不到的,只有想不到的

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

[外链图片转存中…(img-bkfvp8Ls-1713599639012)]

[外链图片转存中…(img-q8LOUmwi-1713599639014)]

相信自己,没有做不到的,只有想不到的

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!针对您的问题,ArcGIS Runtime SDK for Android 支持使用火星坐标系进行定位。您可以通过以下步骤实现: 1. 首先,您需要获取到火星坐标系的参数,包括投影坐标系、椭球体参数等等。这些参数可以从第三方提供的火星坐标系转换库中获取,比如说高德地图 SDK 中提供的 com.amap.api.maps.model.LatLng 对象就是基于火星坐标系的。 2. 在 ArcGIS Runtime SDK 中,您可以使用 ProjectedCoordinateSystem 类来创建一个火星坐标系的投影坐标系对象,例如: ``` SpatialReference marsSR = SpatialReference.create(4490); // 火星坐标系的空间参考编号是 4490 ProjectedCoordinateSystem marsPCS = ProjectedCoordinateSystem.create(marsSR); ``` 3. 接下来,您需要使用 LocationDataSource 类来实现定位功能,其中有一个 setCoordinateSystem 方法可以设置定位坐标系。您可以将火星坐标系的投影坐标系对象传入该方法中,例如: ``` LocationDataSource locationDataSource = new DefaultLocationDataSource(context); locationDataSource.setCoordinateSystem(marsPCS); ``` 4. 最后,您可以使用 MapView 类来展示地图,并在地图上显示当前位置。MapView 中有一个 setViewpointCenterWithAnimation 方法可以将地图视角移动到指定位置,并支持动画效果。例如: ``` MapView mapView = findViewById(R.id.map_view); mapView.setLocationDisplay(locationDisplay); mapView.setViewpointCenterWithAnimation(location, 5000); // 将视角移动到当前位置,并在 5 秒内完成动画效果 ``` 以上就是在 ArcGIS Runtime SDK for Android 中使用火星坐标系进行定位的基本步骤。如果您还有其他问题,欢迎随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值