Android开发笔记(八十)运行状态检查
来源:互联网 发布:菲尼克斯之光 知乎 编辑:程序博客网 时间:2024/06/06 03:38
大家都知道刻舟求剑的寓言故事,说的是事物是发展变化着的,如果拘泥于原来的情况,那随着情况的改变,就不会得到预期的结果。同样,影响app运行的因素,并不只是外部环境(如硬件、系统、权限等等),还包括app自身的运行信息。如果app的运行状态发生了变化,那么原先处理正确的逻辑也可能处理失败,所以在特定的情况下,我们得对app的运行情况进行检查。
1、获得apk的版本号,针对不同版本,分别对SQLite的数据库表做相应的变更操作。
2、获得apk的签名,据此判断安装包是否为合法来源。签名的介绍参见《Android开发笔记(七十三)代码混淆与反破解》。
3、获得apk的申请权限,从而判断app是否申请了相应的权限。权限的介绍参见《Android开发笔记(七十九)资源与权限校验》。
PackageManager类便是获取apk安装信息的工具,该类的getPackageInfo方法即可获得相应的安装信息。下面是getPackageInfo方法中常用标志位参数的说明:
GET_ACTIVITIES : 获取活动Activity列表。列表信息是PackageInfo对象的activities参数。
GET_RECEIVERS : 获取广播接收器Receiver列表。列表信息是PackageInfo对象的receivers参数。
GET_SERVICES : 获取服务Service列表。列表信息是PackageInfo对象的services参数。
GET_SIGNATURES : 获取签名列表。列表信息是PackageInfo对象的signatures参数。
GET_PERMISSIONS : 获取权限列表。列表信息是PackageInfo对象的requestedPermissions参数。
获得PackageInfo实例的代码如下:
下面是PackageInfo类常用的通用参数说明:
packageName : 包名
versionName : 版本名称
versionCode : 版本代码
firstInstallTime : 首次安装时间
lastUpdateTime : 最后更新时间
下面是判断是否为主进程的示例代码:
下面是Application扩展类中的调用代码:
除了上面的例子,还有其它情况可能导致操作UI时的页面丢失,基本上都是些异步操作造成的,比如说处理线程消息的Handler,以及广播接收器BroadcastReceiver。这些情况要想判断Activity页面是否存在,就得借助于ActivityManager的getRunningTasks方法,详细代码如下:
点击下载本文用到的运行状态检查的工程代码
点此查看Android开发笔记的完整目录
apk安装信息
启动app的时候,常常会检查当前apk的安装信息,以此判断接下来要做哪些准备工作,举例如下:1、获得apk的版本号,针对不同版本,分别对SQLite的数据库表做相应的变更操作。
2、获得apk的签名,据此判断安装包是否为合法来源。签名的介绍参见《Android开发笔记(七十三)代码混淆与反破解》。
3、获得apk的申请权限,从而判断app是否申请了相应的权限。权限的介绍参见《Android开发笔记(七十九)资源与权限校验》。
PackageManager类便是获取apk安装信息的工具,该类的getPackageInfo方法即可获得相应的安装信息。下面是getPackageInfo方法中常用标志位参数的说明:
GET_ACTIVITIES : 获取活动Activity列表。列表信息是PackageInfo对象的activities参数。
GET_RECEIVERS : 获取广播接收器Receiver列表。列表信息是PackageInfo对象的receivers参数。
GET_SERVICES : 获取服务Service列表。列表信息是PackageInfo对象的services参数。
GET_SIGNATURES : 获取签名列表。列表信息是PackageInfo对象的signatures参数。
GET_PERMISSIONS : 获取权限列表。列表信息是PackageInfo对象的requestedPermissions参数。
获得PackageInfo实例的代码如下:
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
下面是PackageInfo类常用的通用参数说明:
packageName : 包名
versionName : 版本名称
versionCode : 版本代码
firstInstallTime : 首次安装时间
lastUpdateTime : 最后更新时间
多进程时判断是否为主进程
通常我们会在Application的扩展类中初始化全局变量,方便后续的信息交互,Application的介绍参见《Android开发笔记(二十八)利用Application实现内存读写》。有时候我们又会使用多进程模式,让服务运行在单独的进程中,这样就造成一个问题:新进程是由主进程原样fork出来,即新进程也会执行Application的onCreate方法。但是按照我们的本意,新进程只是为了运行单独的服务,并不需要初始化不相关的全局变量,因此这时候就得判断当前进程是否为主进程。下面是判断是否为主进程的示例代码:
public static boolean isMainProcess(Context ctx) {String processName = "";ActivityManager actMgr = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);for (ActivityManager.RunningAppProcessInfo appProcess : actMgr.getRunningAppProcesses()) {if (appProcess.pid == Process.myPid()) {processName = appProcess.processName;Log.d(TAG, "packageName=" + ctx.getPackageName());Log.d(TAG, "processName=" + processName);}}if (ctx.getPackageName().equals(processName)) {return true;} else {return false;}}
下面是Application扩展类中的调用代码:
public class MainApplication extends Application {private final static String TAG = "MainApplication";@Overridepublic void onCreate() {super.onCreate();if (ActivityUtil.isMainProcess(getApplicationContext()) == true) {//下面初始化主进程的参数Log.d(TAG, "当前是主进程");} else {//这里是分支进程,不处理主进程的参数Log.d(TAG, "当前是分支进程");}}}
Activity是否存在
一般在Activity代码中都是直接操作页面上的元素,不过有时候得小心,页面在操作UI前就不存在了,其中的一个例子可见《Android开发笔记(七十五)内存泄漏的处理》。在上面这篇文章中,我们为了防止Handler的内存泄漏,给Activity加了个弱引用对象,由于弱引用是可以被回收的,因此在使用前得判断弱引用对象是否为空,只有对象非空,才能操作其上的UI元素。除了上面的例子,还有其它情况可能导致操作UI时的页面丢失,基本上都是些异步操作造成的,比如说处理线程消息的Handler,以及广播接收器BroadcastReceiver。这些情况要想判断Activity页面是否存在,就得借助于ActivityManager的getRunningTasks方法,详细代码如下:
public static boolean isActivityWork(Context ctx, String activityName) { boolean isWork = false; ActivityManager actMgr = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> taskList = actMgr.getRunningTasks(1024); for (int i = 0; i < taskList.size(); i++) { String name = taskList.get(i).topActivity.getClassName(); Log.d(TAG, "i="+i+", activity name="+name); if (name.equals(activityName) == true) { isWork = true; break; } } return isWork;}
Service是否存在
与Activity类似,Service也可能被安全软件杀死,导致使用该服务报空指针异常(比如接收广播后调用startForeground方法)。判断后台服务是否存在,与活动的判断一样,都是采用ActivityManager工具类,不同的是,该工具获取服务列表调用的是getRunningServices方法,详细代码如下:public static boolean isServiceWork(Context ctx, String serviceName) { boolean isWork = false; ActivityManager actMgr = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); List<RunningServiceInfo> serviceList = actMgr.getRunningServices(1024); for (int i = 0; i < serviceList.size(); i++) { String name = serviceList.get(i).service.getClassName().toString(); Log.d(TAG, "i="+i+", service name="+name); if (name.equals(serviceName) == true) { isWork = true; break; } } return isWork;}
点击下载本文用到的运行状态检查的工程代码
点此查看Android开发笔记的完整目录
0 0
- Android开发笔记(八十)运行状态检查
- android--笔记--检查读卡器状态
- 学习android开发的小笔记(1)-------- 一个检查android网络状态的程序
- 自动检查mysql运行状态
- Oracle DB 运行状态检查
- Pro Android学习笔记(八十):服务(5):访问远程服务
- 检查Android网络连接状态(转载)
- android 检查网络状态
- android 检查网络状态
- Android检查网络状态
- android 检查联网状态
- android检查网络状态
- Android开发笔记--检查更新app功能
- Android开发笔记:运行程序
- Android:检查网络连接状态
- Android 检查网络连接状态
- 检查Android网络连接状态
- android检查手机网络状态
- 常用文件存储方法参考
- 2705: [SDOI2012]Longge的问题|欧拉函数
- 跟我一起学Microsoft SQL Server 2012 Internals(2.1)
- Valgrind使用说明
- ADT的配置
- Android开发笔记(八十)运行状态检查
- css设置当前鼠标样式
- 《Effctive C++》读书笔记--(02)Prefer consts,enums,and inlines to #defines
- Spring进阶之路(11)-使用Aspectj切面配置和XML配置文件方式实现切面编程
- tcp udp区别
- Android 离线缓存的快速实现
- linux下symfony框架开发网站总结
- IOS 把格式化的JSON字符串转换成字典
- Size Classes介绍