10、Android--技巧
10.1、全局获取Context的技巧
在实践中有很多的地方都可以使用到Context
弹出Toast的时候需要,启动活动的时候需要、发送广播的时候需要、
操作数据库的时候需要、使用通知的时候需要.......
现在的开发中基本上都在使用Context而发愁过
因为操作都是再活动中进行的,活动的本身就是一个Context对象
当应用程序的架构逐渐开始复杂起来的时候
很多的逻辑代码都将脱离Activity类
但是此时由需要使用Context,也许这个时候会感到废脑子
如封装好的网络操作:
此时再方法中添加一个Context参数
并且假设有一个isNetworkAvaiable()方法来判断网路是否可用
虽说上述是一种解决方案,但是却有点推卸责任的嫌疑
因为我们将获取Context的任务转移给sendHttpRequest()方法的调用方
至于用什么方法能不能得到Context对象,那不是我们需要考虑的问题
再某些情况下,获取Context并非是一件容易的事情
有时候还是挺伤脑筋的。
Android提供了一个Application类,每当应用程序启动的时候
系统就会自动将这个类进行初始化
我们可以指定一个自己的Application类
以便于管理程序内一些全局状态的信息
比如全局的Context。
定义自己的Application其实不复杂
首先创建一个MyApplication类继承Application
public class MyApplication extends Application { private static Context context; @Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
} public static Context getContext(){
return context;
}
}
重写父类的onCreate()方法
通过调用getApplicationContext()方法得到一个应用级别的Context
然后提供一个静态的getContext()方法,在这里将获取到的Context进行返回
接下来需要告知系统,当程序启动的时候应该初始化MyApplication类
而不是默认的Application类
再AndroidManifest.xml文件中的<application>标签下进行注册
<activity android:name="com.example.ccrr.material.MyApplication"> </activity>
指定的时候一定要加上完整的包名,不然系统将无法找到这个类
这样就有一套全局获取Context的机制
不管咋任何地放进行使用Context,只需要调用一些:MyAppcation.getContext()方法即可
此时再sendHttpRequest()方法中优化如下:
这里的sendHttpRequest()方法不需要传入参数的方式来得到Context对象
而是调用MyApplication.getContext()方法即可
之前使用的LitePal就能再内部自动获取到Context
已经配置过Application是否会和LitePalApplication产生冲突
任何一个项目都只能配置一个Application
对于这种情况,LitePal提供了更加简单的使用方法
如下:
使用这种写法就相当于把全局的Context对象通过参数传给LitePal
效果和AndroidManifest.xml配置LitePalApplication是一样的
10.2、使用Intent传递对象
Intent在之前的使用已经相当熟悉了
可以借助他来启动活动、发送广播、启动服务等
同时还可以在Intent中添加一些附带的数据,已达到传值的效果
在FirstActivity中
这调用Intent的putExtra()方法来添加要传递的数据
之后再SecondActivity中
但是putExtra()方法中所支持的数据类型是有限的
对常用一些数据类型都是支持的
若是定义一些自定义的对象的时候就会无从下手
下方的有一些技巧
10.2.1、Seriallizable
serializable是序列化的意思
表示将一个对象转换成可存储或者可传输的状态
序列化后的对象可以在网络上进行传输,也可以存储再本地
至于序列化的方法很简单,只需要让一个类实现Serializable这个接口即可
实例:
定义一个Person类,其中包含了name和age这两个字段,实现序列化实现接口即可
其中get、set方法都是用于赋值和读取字段的数据
最重要的一部分再第一行
这里让Person类去实现Serializable接口
这样所有的Person对象都是看可序列化的
然后再FirstActivity中:
这里新建的一个Personde实例
然后就直接将他们传入到putExtra()方法
由于再Person类实现了Serializable接口,所以是这个写法
再SecondActivity中
调用getSerializableExtra()方法获取通过参数传递过来的序列化对象
接着将它转为Person对象
此时成功实现了使用Intent来传递对象的功能
10.2.2、Parcelable方式
除了Serializable之外,使用Parcelable也可以实现相同的效果
不过不同于将对象序列化
Parceleable方式实现的原理是一个将完整的对象进行分家
而后分解的每一部分都是Intent所支持的数据类型,这样就实现了传递对象的功能。
修改Person中的代码
Parcleable的实现方式稍微复杂一些
首先让类实现Parcleable接口,因此必须实现describeContents()方法和writeToParcel()方法
describeContents() 方法直接返回为0即可
writeToParcel() 方法中需要调用Parcel的writeXxx()方法,将Person类中的字段一一写相互
注意:根据数据类型进行调用,string、int....
还需要再Person类中提供一个名为CREATOR的常量
这里创建一个Paraelable.Creator接口的一个实现
接着重写createFromParcel()和newArray()这两个方法
再createFromParcel()方法中读取刚刚写出的name、age字段,并且创建一个Person对象进行返回
其中name个age都是需要调用Parcel的readXxx()方法读取到,这里也需要注意类型string、int,以及读顺序和写顺序相同
再newArray()方法中只需要new一个Person数组,使用方法中传入size作为数组的大小即可
再SecondActivity中:
这里使用getParcelableExtra()方法来获取数据传递过来的对象
其他地方一致
10.3、定制自己的日志工具
对于日志的使用
并且再开发中经常使用做数据测试操作
但是这种使用再日志的控制方面还是做的不是很好
再大型项目中会再很多地方使用日志进行打印
再项目完成时就是再代码中调式的日志问题
在项目上线时还会进行打印,很容易降低程序的运行效率、还有可能将数据泄露出
解决最简单的方式是能够自由地控制日志的打印
当程序处于开发阶段就让日志打印出来
程序上线之后舅把日志屏幕掉
需要定制一个自己的日志工具:
10.4、创建定时任务
定时任务由两种实现方式:
1、使用Java Api里提供的Timer类
2、使用Android的Alarm机制
两种方式在多数情况下都能实现类似的效果
但Timer有一个明显的短板
不适用于那些长期在后台运行的定时任务
为了能让电池更加耐用,每种手机都会由自己的休眠策略
Android手机就会长期在不操作的情况下自动让CPU进入到休眠状态
这就有可能导致Timer中的定时任务无法正常执行
而Alarm具有唤醒CPU的功能
可以保证在大多数情况下需要请求执行任务的时候CPU都能正常工作
唤醒CPU和唤醒屏幕不是一个概念的问题
10.4.1、Alarm机制
主要借助了AlarmManager类来实现的
这个类和NotificationManager有点类似
都是通过调用Context的getSystemService()方法来获取实例
这里需要传入的的参数是Context.ALARM_SERVICE
因此获取一个AlarmManage的实例:
接下来调用AlarmManager的set()方法就可以设置一个定时任务
比如设置一个10秒中后执行,就可以写成:
set()方法需要传入三个参数
1、整形参数,用于指定AlarmManager的工作类型有四个可选值
ELAPSED_REALTIME、ELAPSED_REALTIME_WARKUP、RTC和RTC_WAKEUP
ELAPSED_REALTIME:表示让定时任务的触发时间从系统开机开始算起,但是不会唤醒CPU
ELAPSED_REALTIME_WARKUP:表示让定时任务的触发时间从系统时间开始算起,但是不会唤醒CPU
RTC:表示任务的触发时间是从1970年1月1日0点开始算起,但是会唤醒CPU
RTC_WAKEUP:表示任务的触发时间是从1970年1月1日0点开始算起,但是会唤醒CPU
使用SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数
使用System.currentTimeMills()方法可以获取到1970年1月1日0点至今所经历的毫秒数
2、这个参数是定时任务触发的事件,以毫秒为单位
如果第一个参数使用的是ELAPSED_REALTIME、ELAPSED_REALTIME_WARKUP
这里传入开机至今的事件加上延迟执行的时间
如果第一个参数使用的是RTC、RTC_WAKEUP
这里传入1970年1月1日0点至今的时间在加上延迟的时间
3、此时的参数是一个PendingIntent,这里一般会调用getService()方法或者getBroadcast方法来获取一个能够
执行服务或广播的PendingIntent,这样当任务被触发的时候,服务的onStratCommand()方法或广播接收器
onReceive()方法就可以得到执行
所以此时的set()方法,设定一个任务在10秒钟后执行可以:
如果要实现一个长时间在后台定时运行的服务
首先创建一个普通的服务
再将触发的定时任务代码写在onStratCommand()方法
首先在onStratCommand()方法中开启一个子线程
在这里可以执行一些具体的操作
之所以在子线程中执行逻辑操作
是因为逻辑操作也需要耗时的
在主线程中执行可能会对定时的准确性造成影响
创建线程之后的代码就是Alarm机制的使用
首先获取了AlarmManager的实例
然后在定义任务的触发时间为一小时之后
在使用PendingIntent执行处理定时任务的服务为LongRunningSevice
最后调用set()方法完成设定
这样就定义了一个 长时间在后台运行的服务实现
因为一旦启动了LongRunningService
就会在onStartCommand()方法里设定一个定时任务
这样一个小时后将会再次启动LongRunningServie
从而形成了一个永久的循环
保证LongRuningService的onStratCommand()方法可以每隔一小时就执行一次
注意的是:
4.4系统开始,Alarm任务的触发时间将会变得不准确
有时会延迟一段时间之后任务才能得到执行
这不是一个bug,而是系统对耗电方面性能的优化
系统会自动检测目前有多少个Alarm任务存在
然后触发时间相近的几个任务放在一起执行
这样就可以大幅度减少CPU被唤醒的次数,从而提高电池的使用时间
如果要求Alarm任务的执行时间必须准确无误
Android提供了解决方案
使用AlarmManager的setExact()方法来代替set()方法
基本上就可以保证任务能够准确的执行
10.4.2、Doze模式
虽然Android的每个版本都在手机电量方面的努力进行优化
不过一直没有解决后台服务泛滥、手机电量消耗过快的问题
于是在Android6.0系统中,谷歌加入了一个全新的Doze模式
从而及大幅度的延长电池的使用寿命
首先Doze模式:
当用户设备是一个Android6.0或以上的系统时
如果设备未插电源,处于静止状态,且屏幕关闭了一段时间之后,就会进入Doze模式
早Doze模式下:系统会对CPU、网络、Alarm等活动进行限制,从而延长了电池的使用寿命
系统并不会一直处于Doze模式,而是间接性的退出Doze模式一小段时间
在这段时间中,应用可以完成他们的同部操作、Alarm任务等等
随着设备进入Doze模式的时间越长,间接性的退出Doze模式的时间间隔也会越来越长
因为如果设备长时间不使用的话,是没必要频繁的退出Doze模式来执行同部操作的
Android在这些细节上的把控使得电池寿命进一步得到了延长
Doze模式下会有一些功能会受到限制:
最后一条:
在Doze模式下,我们的Alarm任务将会变得不准时
当然,这在大多情况下是合理的,因为当用户长时间不使用手机才会进入Doze模式
通常这种情况下对ALarm任务的准确性要求没有那么高
真的有特殊需求
需求对Alarm任务模式即使在Doze模式情况下也能必须正常执行
Android还提供了解决方案
调用AlarmManage的setAndAllowWhileIdle()或setExactAndAllowWhileIdle()方法
能够让定时任务即使在Doze模式下也能进行正常执行
这两个方法之间的区别和set()、setExact()方法之间的区别一致。
10、Android--技巧的更多相关文章
- 【转】天啦噜!原来Chrome自带的开发者工具还能这么用!(提升JS调试能力的10个技巧)
天啦噜!原来Chrome自带的开发者工具还能这么用! (提升JS调试能力的10个技巧) Chrome自带开发者工具.它的功能十分丰富,包括元素.网络.安全等等.今天我们主要介绍JavaScript ...
- 编写高性能Web应用程序的10个技巧
这篇文章讨论了: ·一般ASP.NET性能的秘密 ·能提高ASP.NET表现的有用的技巧和窍门 ·在ASP.NET中使用数据库的建议 ·ASP.NET中的缓存和后台处理 使用ASP.NET编写一个We ...
- ExecutorService - 10个技巧和窍门
ExecutorService已经成为Java并发编程中常用的基础库,几乎所有到线程 任务等执行都要委托ExecutorService.下面是使用过程中10个技巧和窍门. 1.为线程池和线程取名 当我 ...
- 让你的 Node.js 应用跑得更快的 10 个技巧(转)
Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...
- 转自微软内部资料:编写高性能 Web 应用程序的 10 个技巧
编写高性能 Web 应用程序的 10 个技巧 转自微软资料数据层性能技巧 1 — 返回多个结果集技巧 2 — 分页的数据访问技巧 3 — 连接池技巧 4 — ASP.NET 缓存 API技巧 5 — ...
- 10个技巧优化PHP程序Laravel 5框架
10个技巧优化PHP程序Laravel 5框架 性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践www.itxdl.c ...
- MAC OS进阶必看——这10个技巧让你秒变MAC达人
文章内容及图片来源于:什么值得买,如果涉及版权问题,请联系作者删除 文章收录于:风云社区(提供上千款各类mac软件的下载) 使用mac系统也有好几个年头,出色的办公效率以及越来越广的兼容性让mac成为 ...
- Eclipse调试Java的10个技巧【转】
clipse调试Java的10个技巧 先提三点 不要使用System.out.println作为调试工具 启用所有组件的详细的日志记录级别 使用一个日志分析器来阅读日志 1.条件断点 想象一下我们平时 ...
- Android技巧分享——如何用电脑下载在Google play中应用的apk文件
[Android技巧分享系列] 1.Android技巧分享——让官方模拟器和genymotion虚拟机飞起来 2.Android技巧分享——如何用电脑下载在Google play中应用的apk文件 G ...
- 2016 Top 10 Android Library
过去的 2016 年,开源社区异常活跃,很多个人与公司争相开源自己的项目,让人眼花缭乱,然而有些项目只是昙花一现,有些项目却持久创造价值,为开发者提供了极大的便利,这些终究由时间来判断.今天,我就来整 ...
随机推荐
- 湘潭校赛 Easy Wuxing
Easy Wuxing Accepted : 25 Submit : 124 Time Limit : 1000 MS Memory Limit : 65536 KB 题目描述 “五行”是中国 ...
- 有序的数据结构中:内存操作红黑树快,磁盘操作b+树快
红黑树常用于存储内存中的有序数据,增删很快,b+树常用于文件系统和数据库索引,因为b树的子节点大于红黑树,红黑树只能有2个子节点,b树子节点大于2,子节点树多这一特点保证了存储相同大小的数据,树的高度 ...
- 一个简单的DLL生成和测试
DLL文件内容: SKLDll.h #ifndef _SKLDLL_H_#define _SKLDLL_H_ #ifndef DLL_API #define DLL_API extern " ...
- Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?
IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...
- CSS字体无法设置成功的问题
在 CSS 中设置字体名称,直接写中文是可以的.但是在文件编码(GB2312.UTF-8 等)不匹配时会产生乱码的错误.xp 系统不支持 类似微软雅黑的中文. 方案一: 你可以使用英文来替代. 比如 ...
- Vue2.0项目打包后只能访问首页,其他页面路径错误找不到
原因是你使用了vue-router的history,可以尝试去掉 // mode:"history",
- CentOS 6.x 安装vnc
https://www.cnblogs.com/pipci/p/7833581.html 1.安装vnc server [root@pxe ~]# yum install tigervnc-ser ...
- ArcGIS10.3+Oracle12C+ArcGIS Server10.3安装布署(之二)
1.创建PDB 输入 dbca 命令 2.安装完成后,连接PDBSDE的容器数据库 3.环境变量 从Oracle的官方网站下载 instantclient-basic-nt-12.1.0.2.0. ...
- arcgis 加载高德地图 es6的方式
目前很多arcgis 加载高德地图是dojo的方式 外部引入文件,现在改成这种方式 /** * Created by Administrator on 2018/5/14 0014. */ impor ...
- maven 超级pom位置、maven命令、构件、下载位置、手动打包位置、中央仓库ip
1.超级pom位置 ----> 解压M2_HOME/lib/maven-model-builder-3.5.4.jar 2.运行maven 命令实际上是运行了 java 命令,因为maven插件 ...