本发明涉及Android开发领域,具体涉及一种应用程序卸载的自我监听方法及其系统。
背景技术:
在Android开发过程中,监听应用程序被安装和是否正在运行很容易做到。但是在运营的时候,运营人员也很希望知道用户卸载APP的数量,这里就需要监控应用程序是否被卸载掉。
通常情况下应用程序被卸载这个过程只有Android系统才可以知道,应用程序是无法感知这个过程的。因为应用程序本身都已经不存在了,所以根本无法知道自己是否被卸载。实际运营过程中为了配合运营人员的需求,需要统计应用程序被卸载的次数。常规方法判断应用程序是否被卸载是通过fork的新进程来循环判断目录中文件是否存在来判定的。这种方法由于轮训的处理IO输入/输出(Input/Output)操作,会导致Android系统资源开销大,同时会影响Android系统的IO效率,对电池电量的损耗也会加大很多。
技术实现要素:
针对现有技术中存在的缺陷,本发明的目的在于提供一种能提高判断应用程序是否被卸载的效率且能降低Android系统功耗开销的应用程序卸载的自我监听方法。
为达到以上目的,本发明采取的技术方案是:
一种应用程序卸载的自我监听方法,用于统计应用程序卸载情况,该方法包括以下步骤:
创建守护进程;
在守护进程中监听Android系统应用程序的卸载广播消息;
解析所述卸载广播消息,获取当前卸载的应用程序的包名信息;以及
判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若否,则需要统计的应用程序未被卸载,若是,则需要统计的应用程序被卸载,然后获取当前卸载的应用程序的卸载信息,并将卸载信息上传至服务器。
在上述技术方案的基础上,通过Linux内核提供的fork函数创建所述新的守护进程。
在上述技术方案的基础上,解析所述卸载广播消息,获取当前卸载的应用程序的包名信息的步骤为在onReceive方法中解析封装到Intent对象中的所述卸载广播消息,并获取Intent对象中当前卸载的应用程序的包名信息。
在上述技术方案的基础上,获取Intent对象中当前卸载的应用程序的包名信息采用调用intent.getData().getSchemeSpecificPart()函数的方式来获取。
在上述技术方案的基础上,调用equals方法来判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若是,equals方法返回true;若否,equals方法返回false。
在上述技术方案的基础上,所述卸载信息包括卸载开始时间信息、卸载状态信息和卸载结束时间信息。
在上述技术方案的基础上,获取卸载开始时间信息和卸载结束时间信息采用调用system.currenttimemillis()函数的方式来获取。
在上述技术方案的基础上,将卸载信息上传至服务器前还包括判定Android系统的CPU使用率的步骤,预设CPU使用率的阈值,若CPU使用率低于所述阈值,则Android系统上传卸载信息至服务器;若CPU使用率高于所述阈值,则开启定时器,设置定时时间,在到了定时时间后进行上传,若到了定时时间后,CPU使用率仍高于所述阈值,则再次开启定时器等待下一次上传,直到上传成功。
与此同时,本发明还提供一种能提高判断应用程序是否被卸载的效率且能降低Android系统功耗开销的应用程序卸载的自我监听系统。
为达到以上目的,本发明采取的技术方案是:
一种应用程序卸载的自我监听系统,包括:
线程创建模块,其用于创建守护进程,所述守护进程用于监听Android系统应用程序的卸载广播消息;
解析模块,其用于解析卸载广播消息,并获取当前卸载的应用程序的包名信息;以及
判断模块,其用于判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若否,则需要统计的应用程序未被卸载,若是,则需要统计的应用程序被卸载,然后获取当前卸载的应用程序的卸载信息,并将卸载信息上传至服务器。
在上述技术方案的基础上,所述应用程序卸载的自我监听系统还包括定时器,所述定时器用于设定定时时间。
与现有技术相比,本发明的优点在于:
(1)本发明的应用程序卸载的自我监听方法,摒弃了常规方法,采取在新的守护进程中捕获监听Android系统程序卸载的广播信息,并对Intent对象的信息进行解析,最后通过包名来判定是否是需要统计的应用程序被卸载。通过监听的方式有效的避免了传统的轮训方式的性能和功耗等各种缺陷问题,极大的提高了Android系统判断应用程序是否卸载的效率,并降低了Android系统的功耗。
(2)本发明中对于卸载结果进行了分析,并设计了自定义的相关传输协议,对协议的扩展也做了相应的处理。同时上传的处理方案中有效的考虑到了Android系统资源和任务的关联系,当Android系统资源不太紧张的时候去处理上传,资源紧张的时候等待下一次的上传触发,达到了上传目的和Android系统资源的平衡性。
附图说明
图1为本发明中应用程序卸载的自我监听方法的流程图;
图2为本发明中应用程序卸载的自我监听系统的结构框图。
具体实施方式
以下结合附图对本发明作进一步详细说明。
参见图1所示,本发明提供一种应用程序卸载的自我监听方法,该方法包括以下步骤:
S1.创建新的守护进程。
本发明采用的是通过Linux内核提供的fork函数创建所述新的守护进程。
由于Android系统本身的限制,Android系统无法去创建一个新的进程。在Linux内核层,内核提供了一个fork函数,fork函数主要功能是在内核层创建一个新的进程。这样就可以通过内核提供的fork函数创建一个新的进程出来。新的进程被创建出来后,即使创建者进程被杀死,被创建的新的进程依旧可以存在并且一直被执行。
当执行fork()函数后,会生成一个子进程,子进程的执行从fork()的返回值开始且代码继续往下执行。fork()执行一次后会有两次返回值:第一次为原来的进程,即父进程会有一次返回值,表示新生成的子进程的进程ID。第二次为子进程的起始执行,返回值为0。如果返回值为-1,则表示创建子进程失败,可以通过errno定位失败原因。
由于Linux内核是使用C语言进行编写的,Java和C通信需要通过JNI技术来进行通信,此时可以利用JAVA来调用C语言的fork函数相关的代码。
新的守护进程的创建过程如下:
1.通过Linux内核提供的fork函数,创建一个新的进程。Fork函数返回值是一个id,Fork函数会返回2次,第一次是原来的父进程id,第二次是返回的子进程id。Fork函数开启的子线程id默认是0,所以可以通过返回的id来进行判断返此进程是不是子进程。
2.创建完子进程以后,便可以通过id的返回值来判断进程是否是子进程。
(a)如果id小于0,说明fork创建失败,可以使用print函数将失败信息打印出来。其中print函数是C语言专门负责将信息输出到控制台的函数。
(b)如果id大于0,说明此时返回的是父进程的id,为了调试方便,可以在父进程中输出父进程的id号。输出方式也是通过调用print函数来将父进程的id输出到控制台上。
(c)如果id等于0,说明此时返回的是子进程,后续处理异常信息的线程是在子线程中进行处理的,此处仅仅只输出子进程的进程id号到控制台,方便后续调试使用。
如果第一次返回的id大于0,第二次返回的id等于0,说明整个创建过程执行成功。如果其中任何一个id小于0说明fork这个函数执行失败了。如果fork函数执行失败,说明创建子进程失败,此时将失败结果输出到控制台上。
通过上述方法可以开启一个新的守护线程newProcess,后面可以使用这个线程去监控应用程序是否被卸载。
S2.在守护进程中监听Android系统应用程序的卸载广播消息。
为了能够监听到应用程序的卸载,本发明中使用了广播监听的技术来监听Android系统的卸载广播信息。并对监听到的卸载广播信息进行解析,解析完成后如果发现是需要统计的应用程序被卸载了,此时会进一步对卸载部分进行统计和分析。如果是不需要统计的应用程序被卸载,则不会做进一步处理。
通常,在Android系统中,应用程序被卸载的广播消息是Intent.ACTION_PACKAGE_REMOVED,通过监听Android系统的Intent.ACTION_PACKAGE_REMOVED广播消息,就能够知道应用程序是否被卸载了。
若应用程序被卸载掉了,Android系统便会发送Intent.ACTION_PACKAGE_REMOVED这个广播消息,也就是说Intent.ACTION_PACKAGE_REMOVED的消息对应着一个应用程序的卸载。
当应用程序被卸载后,Android系统会回到onReceive方法,在onReceive方法中去解析Android系统应用程序卸载的详细信息。当程序被卸载的时候,Android系统会将卸载的数据封装到Intent对象中,拿到Intent对象后对Intent对象来进行解析,就能够获取当前卸载的应用程序的包名信息。
S3.解析卸载广播消息,获取当前卸载的应用程序的包名信息;
为了能够获取当前卸载的应用程序的包名信息,需要对Intent对象进行解析,从Intent对象中解析出来对应的应用程序的包名信息。
本发明中是通过调用intent.getData().getSchemeSpecificPart()函数,来获取Intent对象中被卸载的应用程序的包名信息。
S4.判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若否,则需要统计的应用程序未被卸载,停止处理,结束。若是,则需要统计的应用程序被卸载,然后获取当前卸载的应用程序的卸载信息,并将卸载信息上传至服务器,结束。
本发明中采用的是调用equals方法来判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若是,equals方法返回true;若否,equals方法返回false。
常规方法判断应用程序是否被卸载是通过fork的新进程来循环判断目录中文件是否存在来判定的。这种方法由于轮训的处理IO输入/输出(Input/Output)操作(本发明中主要指的是文件的读取和写入操作),会导致Android系统资源开销大的同时还会影响Android系统的IO效率,对电池电量的损耗也会加大很多。
本发明摒弃了常规方法,采取在新的守护进程中捕获监听Android系统程序卸载的广播信息,并对Intent对象的信息进行解析,最后通过包名来判定是否是需要统计的应用程序被卸载。
通过监听的方式有效的避免了传统的轮训方式的性能和功耗等各种缺陷问题,极大的提高了Android系统判断判断应用程序是否卸载的效率,并降低了Android系统的功耗。
此外,应用程序被删除后,可以获取应用程序卸载时间点,卸载时间长度,还有卸载的状态等信息,并将这些信息传递到服务器进行备份处理。如果卸载成功了,fork出来的线程会给出Toast的提示信息。
下面详细描述应用程序卸载后对卸载信息处理操作,其中卸载信息包括卸载开始时间信息、卸载状态信息和卸载结束时间信息。
1.获取卸载应用程序的卸载开始时间信息
为了获取应用程序被卸载的卸载开始时间信息,Android系统会在应用程序开始卸载的时候发送一个卸载开始的广播消息,此时通过监听的方式便可以获取到该开始卸载的广播消息,并在该广播消息的接受函数onReceiver函数中记录当前开始卸载的时间点。
本发明中获取当前开始卸载的时间点的方法是通过调研system.currenttimemillis()函数来获取当前的Android系统的时间信息。本发明中将获取到的开始时间信息标记为startTime。
2.获取卸载状态信息,并提示
接下来通过上述的监听方法来判定应用程序是否被卸载掉了,若应用程序被卸载,此时会发送一个提示信息来告知用户应用程序被卸载掉了。提示信息是通过Toast中的show方法来给用户提示消息的。
3.获取卸载应用程序的卸载结束时间信息
当检测到应用程序的目录不存在的时候,此时说明应用程序被卸载完成了。这个时候需要将应用程序的卸载时间点记录下来,记录应用程序卸载完成时间的方法是通过system.currenttimemillis()来获取的。本发明中标记卸载完成的时间点为stopTime
4.将卸载信息封装后上传服务器
接下来将上述卸载信息进行封装,然后将封装后的卸载信息提交到服务器,方便运维人员对其进行分析和处理。
设计协议如下:
上述协议中:
startTime:开始卸载的时间点
stopTime:卸载成功的时间点
status:状态信息,表明是卸载
version:卸载的当前应用程序的版本号信息。
extra:”扩展字段”,起到了对协议的升级的作用,当前协议中extra字段无作用,后续协议升级的时候可以使用到。
将上述获取到的卸载信息封装到自定义的协议中,然后将该数据上传到服务器,服务器再对其进行处理。
5.上传服务器的触发条件
默认情况下是当上述卸载信息被解析完成后,便可直接上传到服务器,本发明中为了兼顾Android系统资源的开销,对上传服务器的方式做了更好的优化处理。
具体的,在准备上传的时候会去判定Android系统的CPU使用率,预设一个CPU使用率的阈值,本发明中的阈值为80%。如果CPU使用率低于80%,此时直接进行上传操作。如果CPU使用率大于等于80%,为了不影响Android系统的资源开销,此时会开启定时器,设定定时时间,本发明中设置定时时间为5分钟后再进行上传。如果5分钟后检测CPU还是高于80%,再次开启定时器等待下一次上传,这样循环下去直到上传成功。
本发明中对于卸载结果进行了分析,并设计了自定义的相关传输协议,对协议的扩展也做了相应的处理。同时上传的处理方案中有效的考虑到了Android系统资源和任务的关联系,当Android系统资源不太紧张的时候去处理上传,资源紧张的时候等待下一次的上传触发,达到了上传目的和Android系统资源的平衡性。
参见图2所示,本发明还提供一种应用程序卸载的自我监听系统,包括线程创建模块、解析模块、判断模块和定时器。
线程创建模块,其用于创建守护进程,守护进程用于监听Android系统应用程序的卸载广播消息。
解析模块,其用于解析卸载广播消息,并获取当前卸载的应用程序的包名信息。
判断模块,其用于判断当前卸载的应用程序的包名信息是否是需要统计的应用程序的包名信息,若否,则需要统计的应用程序未被卸载,若是,则需要统计的应用程序被卸载,然后获取当前卸载的应用程序的卸载信息,并将卸载信息上传至服务器。
定时器,其用于设定定时时间。
本发明不局限于上述实施方式,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也视为本发明的保护范围之内。本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。