Perhaps some of the students who use Alarmmanager to do timed tasks encounter this problem: After setting up alarm, go to Settings--application management--After you force stop the app, the scheduled task expires.
To put it simply: Force stop causes alarm to fail.
The most typical example is a bug that I've encountered, setting an alarm clock using the Android phone's clock app, and then going into settings--app management, the clock app force stop off, and the alarm doesn't ring.
In fact, this is not a bug, this is the new Android system to join the mechanism. Let me analyze the ins and outs in detail below.
1. Force the app to stop in the app management settings:
This will eventually be called to Activitymanagerservice's forcestoppackagelocked ()
The source code is as follows:
<span style= "font-size:18px" >Private voidForcestoppackagelocked (FinalString PackageName,intuid) {forcestoppackagelocked (PackageName, UID,false,false,true,false); Intent Intent=NewIntent (intent.action_package_restarted, Uri.fromparts ("Package", PackageName,NULL)); if(!Mprocessesready) {intent.addflags (intent.flag_receiver_registered_only); } Intent.putextra (Intent.extra_uid, UID); Broadcastintentlocked (NULL,NULL, Intent,NULL,NULL, 0,NULL,NULL,NULL, false,false, My_pid, Process.system_uid); }</SPAN>Private voidForcestoppackagelocked (FinalString PackageName,intuid) {forcestoppackagelocked (PackageName, UID,false,false,true,false); Intent Intent=NewIntent (intent.action_package_restarted, Uri.fromparts ("Package", PackageName,NULL)); if(!Mprocessesready) {intent.addflags (intent.flag_receiver_registered_only); } Intent.putextra (Intent.extra_uid, UID); Broadcastintentlocked (NULL,NULL, Intent,NULL,NULL, 0,NULL,NULL,NULL, false,false, My_pid, Process.system_uid); }
The code sends a broadcast: Action_package_restarted, the broadcast great article.
2. Look at the Alarmmanagerservice.java code, you can see an internal class Uninstallreceiver
The source code is as follows:
[Java]<span style= "font-size:18px" >classUninstallreceiverextendsBroadcastreceiver { PublicUninstallreceiver () {intentfilter filter=NewIntentfilter (); Filter.addaction (intent.action_package_removed); Filter.addaction (intent.action_package_restarted); Filter.addaction (Intent.action_query_package_restart); Filter.adddatascheme ("Package"); Mcontext.registerreceiver ( This, filter); //Register for events related to SDcard installation. Intentfilter Sdfilter =NewIntentfilter (); Sdfilter.addaction (intent.action_external_applications_unavailable); Mcontext.registerreceiver ( This, Sdfilter); } @Override Public voidOnReceive (Context context, Intent Intent) {synchronized(MLock) {String action=intent.getaction (); String pkglist[]=NULL; if(Intent.ACTION_QUERY_PACKAGE_RESTART.equals (ACTION)) {pkgList=Intent.getstringarrayextra (intent.extra_packages); for(String packagename:pkglist) {if(lookforpackagelocked (PackageName)) {Setresultcode (ACTIVITY.RESULT_OK); return; } } return; } Else if(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals (ACTION)) {pkgList=Intent.getstringarrayextra (intent.extra_changed_package_list); } Else { if(Intent.ACTION_PACKAGE_REMOVED.equals (ACTION)&& Intent.getbooleanextra (intent.extra_replacing,false)) { //This is being updated, and don ' t kill its alarms. return; } Uri Data=Intent.getdata (); if(Data! =NULL) {String pkg=Data.getschemespecificpart (); if(Pkg! =NULL) {pkgList=Newstring[]{pkg}; } } } if(PkgList! =NULL&& (Pkglist.length > 0)) { for(String pkg:pkglist) {removelocked (pkg); Mbroadcaststats.remove (pkg); } } } } }</SPAN>classUninstallreceiverextendsBroadcastreceiver { PublicUninstallreceiver () {intentfilter filter=NewIntentfilter (); Filter.addaction (intent.action_package_removed); Filter.addaction (intent.action_package_restarted); Filter.addaction (Intent.action_query_package_restart); Filter.adddatascheme ("Package"); Mcontext.registerreceiver ( This, filter); //Register for events related to sdcard installation.Intentfilter Sdfilter =NewIntentfilter (); Sdfilter.addaction (intent.action_external_applications_unavailable); Mcontext.registerreceiver ( This, Sdfilter); } @Override Public voidOnReceive (Context context, Intent Intent) {synchronized(MLock) {String action=intent.getaction (); String pkglist[]=NULL; if(Intent.ACTION_QUERY_PACKAGE_RESTART.equals (ACTION)) {pkgList=Intent.getstringarrayextra (intent.extra_packages); for(String packagename:pkglist) {if(lookforpackagelocked (PackageName)) {Setresultcode (ACTIVITY.RESULT_OK); return; } } return; } Else if(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals (ACTION)) {pkgList=Intent.getstringarrayextra (intent.extra_changed_package_list); } Else { if(Intent.ACTION_PACKAGE_REMOVED.equals (ACTION)&& Intent.getbooleanextra (intent.extra_replacing,false)) { //This is being updated, and don ' t kill its alarms. return; } Uri Data=Intent.getdata (); if(Data! =NULL) {String pkg=Data.getschemespecificpart (); if(Pkg! =NULL) {pkgList=Newstring[]{pkg}; } } } if(PkgList! =NULL&& (Pkglist.length > 0)) { for(String pkg:pkglist) {removelocked (pkg); Mbroadcaststats.remove (pkg); }}}} visible Alarmmanagerservice accepted the action_package_restarted broadcast and executed the removelocked (pkg) Remo What does velocked () do? Continue to see source code: [Java]<span style= "font-size:18px" > Public voidremovelocked (String packagename) {removelocked (mrtcwakeupalarms, PackageName); Removelocked (Mrtcalarms, PackageName); Removelocked (Melapsedrealtimewakeupalarms, PackageName); Removelocked (Melapsedrealtimealarms, PackageName); } Private voidRemovelocked (arraylist<alarm>alarmlist, String packagename) { if(Alarmlist.size () <= 0) { return; } //iterator over the list removing any it where the intent matchIterator<alarm> it =Alarmlist.iterator (); while(It.hasnext ()) {Alarm Alarm=It.next (); if(Alarm.operation.getTargetPackage (). Equals (PackageName)) {it.remove (); } } }</SPAN> Public voidremovelocked (String packagename) {removelocked (mrtcwakeupalarms, PackageName); Removelocked (Mrtcalarms, PackageName); Removelocked (Melapsedrealtimewakeupalarms, PackageName); Removelocked (Melapsedrealtimealarms, PackageName); } Private voidRemovelocked (arraylist<alarm>alarmlist, String packagename) { if(Alarmlist.size () <= 0) { return; } //iterator over the list removing any it where the intent matchIterator<alarm> it =Alarmlist.iterator (); while(It.hasnext ()) {Alarm Alarm=It.next (); if(Alarm.operation.getTargetPackage (). Equals (PackageName)) {it.remove (); } } }
See here, you should understand, removelocked is the corresponding package set of all types of alarm removed.
See here you should know why the alarm you set up will not work?
Thinking:
Why does Google want to join such a mechanism?
It should be for the sake of system security, Google in the 4.0 system in the security of a lot of efforts.
Many virus programs do not want their process by the user forcibly stop, hope that their own virus program can continue to run, and the common way is to set up the alarm, after the virus process was killed, by timed to send a broadcast to pull up the virus process, to implement the virus process restart.
Google also saw this point, so joined the forcestoppackage mechanism, so that users can have the opportunity to kill the virus process.