某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法
在某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异常的解决方法的更多相关文章
- 关于C#使用Dllimport 导入vc++动态库后网站部署提示 “无法加载 DLL,找不到指定模块”的解决方法。
这次项目需要,做了一个C#写的WebService服务给外部调用,服务内部引用了算法库,本地调试已经通过,现场部署服务时各种提示找不到DLL文件. 第一.如果是包含有32位库在64位服务器系统上运行, ...
- jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法
博客分类: jquery-easyui jQueryAjax框架HTML 现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...
- 用C3中的animation和transform写的一个模仿加载的时动画效果
用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...
- mvc中多参数URL会很长,首次加载不传参数让url很短,路由规则实现方法[bubuko.com]
如要实现列表中地址全路径“bubuko-11-2.html”,在首次进入时,使用短路径“bubuko.html”,只有再次href后才显示全路径“bubuko-11-2.html”,下面使用路由规则来 ...
- Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法。
Win7系统中提示:本地无法启动MySQL服务,报的错误:1067,进程意外终止的解决方法. 在本地计算机无法启动MYSQL服务错误1067进程意外终止.这种情况一般是my.ini文件配置出错了1.首 ...
- win7,vs2010,asp.net项目中修改外部js文件,在调试时加载的还是旧文件
win7,vs2010,asp.net项目中修改外部js文件,在调试时加载的还是旧文件 我杀过 w3wp.exe和asp.net_state的进程,重启 iis admin的服务,都还是不行. 只是把 ...
- Java中的ExceptionInInitializerError异常及解决方法
当在静态初始化块中出现了异常的时候,JVM会抛出 java.lang.ExceptionInInitializerError异常.如果你了解Java中的静态变量,你会知道它们是在类加载的时候进行初始化 ...
- PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题
PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题,PageSlider中加入CSS3动画的话,默认只有首屏是从无到有执行动画,其他屏都是显示下页面再执行动画 这就造成其他屏的动 ...
- Windows -- 从注册表删除IE浏览器加载项
Windows -- 从注册表删除IE浏览器加载项 1. 一部分加载项从注册表以下位置直接删除 2. 一部分扩展项从注册表以下位置直接删除
随机推荐
- javascript系统时间
<div> <%--系统时间--%> 当前时间是: <script type=& ...
- c#转码解码
///反转码 mdata[k].MNAME = unescape(mdata[k].MNAME);程家楠 13:51:00 Microsoft.JSc ...
- jquery操作iframe
query取得iframe中元素的几种方法 在iframe子页面获取父页面元素 代码如下: $('#objId', parent.document); // 搞定... 在父页面 获取iframe子页 ...
- AngularJs练习Demo4
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- 如何修改UIButton按下后默认的蓝色效果
其实有两个简单方法:1.修改xib属性检查器Highlight Tint的值: 2.通过代码修改:btn.tintColor=[UIColor grayColor];或者[btn setTintCol ...
- UIView / UIView的布局
//! 一个视图可以有n个子视图,但是一个视图只能有一个父视图 struct CGRect { CGPoint origin; CGSize size; }; CGRectMake(CGFlo ...
- CC开发问题一
CC编译成功,启动失败,debug状态下报错如下,未能加载文件或程序集 这个问题查了一些资料,http://blog.csdn.net/shellching/article/details/82947 ...
- hdu Big Number 求一个数的位数
Problem Description In many applications very large integers numbers are required. Some of these app ...
- Java中循环删除list中元素的方法总结
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...
- show_space/get_alert_log/get_trace_file
1.get_alert_log 获取alert文件的路径和名称 set serveroutput on --设置输出,让sqlplus在屏幕上可以输出.(要加入到login.sql中!) ...