首先,存储在磁盘上的图片是被压缩过的(以JPG,PNG或类似的格式存储)。 一旦将图片加载到内存中,它就不再被压缩,并占用尽可能多的图片的所有像素所需的内存空间。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名申请、网页空间、营销软件、网站建设、昌平网站维护、网站推广。
其次,加载大图的步骤:
1.获取图片的宽和高:BitmapFactory.Options
BitmapFactory可以为我们提供图片的元数据。我们可以使用这个类来实现第一步。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =true;//不想将图片加载到内存中。获取图片的相关信息(宽度,高度等),并使用这些信息来计算缩放比例。
BitmapFactory.decodeResource(getResources(), R.mipmap.hqimage, options);
2.根据图片的宽和高计算缩放比Reducing Image Size (In Memory)
:现在我们需要计算 inSampleSize 。其是BitmapFactory.Options类的一个属性,用于设置图片的缩放比。
如果我们有一张尺寸为1000x1000的图片,并且在解码之前设置inSampleSize的值为2, 那么解码之后,我们将得到一张尺寸为500x500的图片。
BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds =true;options.inSampleSize = 3; BitmapFactory.decodeResource(getResources(), R.mipmap.hqimage, options);
注意:inSampleSize 设置为 5 , 最终 会被 取整为 4
3.根据缩放比将图片加载到内存中。Reducing Image Size (In Disk)
我们还可以使用Bitmap的 compress 方法对磁盘上的图片进行压缩。我们来看看在不改变图片质量的情况下图片被压缩后的大小。 100 表示与原图保持相同的质量。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
通过计算得到图片在磁盘上的大小为1.6 MB。
我们把compress方法中的质量参数改为50,并再次计算图片大小
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bos);
通过计算得到图片在磁盘上的大小为24.4 KB。
注意 :在改变compress方法中的质量参数的时候,压缩格式应该是.JPEG。设置为PNG格式的时候,修改是无效的。
对double数据类型进行四舍五入运算,可以利用double转为整型时强制取整来做到。 1 将double类型数据,强制转换为int类型,会强制截取整数部分。比如double a = 1.23; (int)a的值就是1。 2 由于是强制取整,所以即使是1.9转为int后,同样是1,这与四舍五入的要求不符。所以可以转换一下算法,做(int)(a+0.5)就可以实现四舍五入到整数的效果了。 3 要实现四舍五入到某一位,可以先乘一个值,将该位移动到个位,取整后,再除上这个值,将其移动回去。 比如将double a = 1.2345四舍五入保留2位小数,可以写作 (int)(a*100+0.5)/100.0。
首先在程序需要中对INT型变量/代表取整运行,注意区分它们的不同,而%只能用于整数,取余运算 5%13=5,5除以13商0余5。
java取余运算:
取余(或余数)运算符用 number1 除以 number2 (把浮点数四舍五入为整数),然后只返回余数作为 result。
通常取模运算也叫取余运算,他们都遵循处罚法则,返回结果都是余数;
Java中取余运算具有如下性质:对所有int数值a和所有非零int数值b满足:(a / b ) * b + (a % b) == a;
这意味着当取余操作返回一个非零的结果时。它与左操作数具有相同的正负符号。
currentGeoPoint 是当前位置的坐标。
currentGeoPoint.getLatitudeE6() 是获得当前坐标的纬度。
1E6 就是10的6次方 也就是1000000.
这句代码的意思就是:将当前坐标的纬度除以1000000以后取整,再转成字符串。
在开发倒计时功能时往往我们会为了方便直接使用CountDownTimer或者使用Handler做延时来实现,当然CountDownTimer内部封装也是使用的Handler。
如果只是做次数很少的倒计时或者不需要精确的倒计时逻辑那倒没关系,比如说我只要倒计时10秒,或者我大概5分钟请求某个接口
但是如果是需要做精确的倒计时操作,比如说手机发送验证码60秒,那使用现有的倒计时方案就会存在问题。可能有些朋友没有注意到这一点,下面我们就来简单分析一下现有倒计时的问题。
这个可能是用得最多的,因为方便嘛。但其实倒计时每一轮倒计时完之后都是存在误差的,如果看过CountDownTimer的源码你就会知道,他的内部是有做 校准操作 的。(源码很简单这里就不分析了)
但是如果你认真的测试过CountDownTimer,你就会发现,即便它内部有做校准操作,他的没一轮都是有偏差,只是他最后一次倒计时完之后的总共时间和开始倒计时的时间相比没偏差。
什么意思呢,意思就是1秒,2.050秒,3.1秒......,这样的每轮偏差,导致他会出现10.95秒,下一次12秒的情况,那它的回调中如果你直接做取整就会出现少一秒的情况,但实际是没少的。
这只是其中的一个问题,你可以不根据它的回调做展示,自己用一个整形累加做展示也能解决。但是他还有个问题,有概率直接出现跳秒,就是比如3秒,下次直接5秒,这是实际的跳秒,是少了一次回调的那种。
跳秒导致你如果直接使用它可能会大问题,你可能自测的时候没发现,到时一上线应用在用户那概率跳秒,那就蛋疼了。
不搞这么多花里胡哨的,直接使用Handler来实现,会有什么问题。
因为直接使用handler来实现,没有校准操作,每次循环会出现几毫秒的误差,虽然比CountDownTimer的十几毫秒的误差要好, 但是在基数大的倒计时情况下误差会累计,导致最终结果和现实时间差几秒误差,时间越久,误差越大
直接使用Timer也一样,只不过他每轮的误差更小,几轮才有1毫秒的误差,但是没有校准还是会出现误差累计,时间越久误差越大。
既然无法直接使用原生的,那我们就自己做一个。
我们基于Handler进行封装,从上面可以看出主要为了解决两个问题,时间校准和跳秒。自己写一个CountDownTimer
思路就是在倒计时开始前获取一次SystemClock.elapsedRealtime(),没轮倒计时再获取一次SystemClock.elapsedRealtime()相减得到误差,根据delay校准。然后使用while循坏来处理跳秒的操作,与原生的CountDownTimer不同,这里如果跳了多少秒,就会返回多少次回调。
rowSpec和columnSpec分别设置了一个按钮的位置是第几行和第几列。
(i / 4 + 2)的意思是String[] chars中id为i的元素,所处行数是i/4+2。因为i是int型,所以i/4向下取整。至于那个+2,无所谓的。
i%4的意思是i/4后的余数,因为计算器排版中一行有4个元素,所以比如2这个元素,它在String[] chars中id是9,那么他的位置是9/4的余数,也就是1,列数用0,1,2,3表示,所以它在第二列。