当前位置:操作系统 > 安卓/Android >>

android安全:forceStopPackage对android的Alarm的影响

 也许一些使用alarmmanager做定时任务的同学遇到过这样的问题:设定alarm后,进入设置-->应用程序管理-->强行停止app后,定时任务就失效了。

 


简单的讲就是:force stop会导致alarm失效。

 


最典型的例子就是我碰到过的一个bug,使用android手机的时钟app设置一个闹钟,然后进入设置-->应用程序管理里面,将时钟这个app force stop掉,结果闹钟就不响了。

 


其实这不是bug,这是android系统的新加入的机制。下面我来详细分析一下来龙去脉。

 


1. 在设置的应用程序管理里面强行停止app:

    这里会最终会调用到 ActivityManagerService的forceStopPackageLocked()

源代码如下:


[java]
<SPAN style="FONT-SIZE: 18px">    private void forceStopPackageLocked(final String packageName, int uid) { 
        forceStopPackageLocked(packageName, uid, false, false, true, false); 
        Intent intent = new Intent(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 void forceStopPackageLocked(final String packageName, int uid) {
        forceStopPackageLocked(packageName, uid, false, false, true, false);
        Intent intent = new Intent(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);
    }
代码里面发送了一个广播:ACTION_PACKAGE_RESTARTED,这个广播大有文章。

2. 再看看AlarmManagerService.java的代码,可以看一个内部类UninstallReceiver

源代码如下:


[java]
<SPAN style="FONT-SIZE: 18px">class UninstallReceiver extends BroadcastReceiver { 
        public UninstallReceiver() { 
            IntentFilter filter = new IntentFilter(); 
            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 = new IntentFilter(); 
            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 
            mContext.registerReceiver(this, sdFilter); 
        } 
         
        @Override 
        public void onReceive(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

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,