在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下:

    @Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow(); /* monitor time ticks, time changed, timezone */ if (mIntentReceiver == null)
{
mIntentReceiver = new TimeChangedReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter);

Launcher要动态加载此APK(动态加载APK的目的和实现思路,参见我的这个文章: Launcher中动态加载其它APK中Activity的问题解决思路 ),

出现了如下异常:

09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

搜索了一下,很多人遇到过此类问题,但都没有提出解决方法,看来只能自己动手解决了。

动态加载不行,那在AndroidManifest.xml试试静态加载BroadcastReceiver是否可以?

如果是其它的BroadcastRecevier,验证了是ok的,但android.content.Intent.ACTION_TIME_TICK这个不行,Android的注释中已经明确说明了。

String android.content.Intent.ACTION_TIME_TICK = "android.intent.action.TIME_TICK"

Broadcast Action: The current time has changed. Sent every minute. You can not receive this through components declared in manifests, only by exlicitly registering for it with Context.registerReceiver(). 

This is a protected intent that can only be sent by the system.

难道就真的没有解决方法了?

手头有一份Android源码,我根据“Given caller package”和“is not running in process ProcessRecord”这两个关键字全文搜索,

想看看抛出这个异常的代码是在哪里搞出来的,在*.cpp,*.c*,*.java中搜索都没有找到,先放弃此方法吧。

回头再来分析此异常,

09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

我是在第三方APK中注册的BroadcastReceiver,这个APK在AndroidManifest.xml中声明的包名正好是“com.zhao3546.time”,而最终是和Launcher运行在同一个进程中的,这个进程对应的包名是“com.zhao3546.launcher”,因为Launcher先运行,而APK是被动态加载进来的。

那是不是只要我注册BroadcastReceiver对应的包名只要是“com.zhao3546.launcher”,就可以解决问题了?

Launcher中动态加载其它APK中Activity的问题解决思路,此文中已经通过将Launcher和第三方APK的AndroidManifest.xml中android:sharedUserId属性声明成为一致了,

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zhao3546.time"
android:sharedUserId="zhao3546.launcher"

所以Launcher和第三方APK实际上是运行在同一个进程中的,那只要将Launcher的context对象传给这个APK,这个APK使用Launcher的context去注册BroadcastReceiver,是不是就可以解决问题了?

第三方APK的com.zhao3546.time包下新增如下类,并实现有public static void setContext(Context context)这个静态方法:

package com.zhao3546.time;

import android.content.Context;

public class ContextHolder
{
private static Context context = null; public static void setContext(Context context)
{
System.out.println("com.zhao3546.time.ContextHolder setContext"); ContextHolder.context = context;
} public static Context getContext()
{
System.out.println("com.zhao3546.time.ContextHolder getContext() context="
+ context); return context;
}
}

在Launcher代码中,通过反射机制动态地将launcher的context对象传到 com.zhao3546.time.ContextHolder 中,

    private void setContext2Plugin(ClassLoader pluginClassLoader,
String pluginPackageName, Context launcherContext)
{
String className = pluginPackageName + ".ContextHolder";
try
{
Method m = pluginClassLoader.loadClass(className)
.getMethod("setContext", Context.class);
m.invoke(null, launcherContext);
}
catch (Exception e)
{
Log.w(TAG, "Fail to loadClass " + className + ", skip it", e);
}
}

修改之前注册BroadcastReceiver的地方,通过ContextHolder()来注册BroadcastReceiver,把APK重新部署验证,问题解决。

看似解决不了的问题,其实有时需要换个思路去尝试不同的方法,可能就会取得意想不到的效果。

某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法的更多相关文章

  1. 关于C#使用Dllimport 导入vc++动态库后网站部署提示 “无法加载 DLL,找不到指定模块”的解决方法。

    这次项目需要,做了一个C#写的WebService服务给外部调用,服务内部引用了算法库,本地调试已经通过,现场部署服务时各种提示找不到DLL文件. 第一.如果是包含有32位库在64位服务器系统上运行, ...

  2. jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法

    博客分类: jquery-easyui jQueryAjax框架HTML  现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...

  3. 用C3中的animation和transform写的一个模仿加载的时动画效果

    用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...

  4. mvc中多参数URL会很长,首次加载不传参数让url很短,路由规则实现方法[bubuko.com]

    如要实现列表中地址全路径“bubuko-11-2.html”,在首次进入时,使用短路径“bubuko.html”,只有再次href后才显示全路径“bubuko-11-2.html”,下面使用路由规则来 ...

  5. Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法。

    Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法. 在本地计算机无法启动MYSQL服务错误1067进程意外终止.这种情况一般是my.ini文件配置出错了1.首 ...

  6. win7,vs2010,asp.net项目中修改外部js文件,在调试时加载的还是旧文件

    win7,vs2010,asp.net项目中修改外部js文件,在调试时加载的还是旧文件 我杀过 w3wp.exe和asp.net_state的进程,重启 iis admin的服务,都还是不行. 只是把 ...

  7. Java中的ExceptionInInitializerError异常及解决方法

    当在静态初始化块中出现了异常的时候,JVM会抛出 java.lang.ExceptionInInitializerError异常.如果你了解Java中的静态变量,你会知道它们是在类加载的时候进行初始化 ...

  8. PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题

    PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题,PageSlider中加入CSS3动画的话,默认只有首屏是从无到有执行动画,其他屏都是显示下页面再执行动画 这就造成其他屏的动 ...

  9. Windows -- 从注册表删除IE浏览器加载项

    Windows -- 从注册表删除IE浏览器加载项 1.  一部分加载项从注册表以下位置直接删除 2.  一部分扩展项从注册表以下位置直接删除

随机推荐

  1. samba错误

    1.session setup failed: NT_STATUS_LOGON_FAILURE 该错误表示用户有误, 可能是用户不存在, 也有可能是密码错误, 或者用户只是在samba和系统的用户中的 ...

  2. c#基础: 线程的初级用法总结

    启动一个线程的两种方法:     a.使用无参的方法       Thread thread1 = new Thread(new ThreadStart("调用的方法名")):   ...

  3. shell常用命令的用法

    1. 如何把 /etc/passwd 中用户uid 大于500 的行给打印出来?awk -F ':' '$3>500' /etc/passwd 2. awk中 NR,NF两个变量表示什么含义?N ...

  4. HTML与CSS入门——第十章 创建用于Web上的图像

    知识点: 1.选择图像软件的方法 2.准备用于网上的照片的方法 3.创建标题和按钮的方法 4.减少图像中颜色数量的方法 5.创建透明图像的方法 6.创建平铺背景的方法 7.创建Web动画的方法 10. ...

  5. c#类初始化器

    其实类型初始化器只是一种语法糖这样写MyClass a=new MyClass{ filedOne="a" ,filedTwo="b" };会被编译器编译成和如 ...

  6. js过滤

    datagrid:                loadFilter: function (data) {                    return loadFilter(data);   ...

  7. validatebox验证框架rules

    项目前端使用JQuery easyui框架,验证使用插件validatebox,验证方法如下: <input name="test" type="text" ...

  8. JS对象排序

    function createComparisonFunction(propertyName) {return function(object1, object2){var value1 = obje ...

  9. WDCP LNMPA和LNMP 504 Gateway time-out错误的解决方法

    Nginx的特点是处理静态很给力,Apache的特点是处理动态很稳定,两者结合起来便是LNMPA,nginx处理前端,apache处理后端,这样处理静态会很快,处理动态会很稳定.当我以为安装完成以后便 ...

  10. 异常处理:你不可能总是对的 - 零基础入门学习Python032

    异常处理:你不可能总是对的 让编程改变世界 Change the world by program 因为我们是人,不是神,所以我们经常会犯错.当然程序员也不例外,就算是经验丰富的码农,也不能保证写出来 ...