范型&&诡异异常
来源:互联网 发布:鄂尔多斯网络推广招聘 编辑:程序博客网 时间:2024/06/05 22:01
Looper 中是使用一个ThreadLocal 来存储 当前线程的 looper的,
static final ThreadLocal sThreadLocal = new ThreadLocal();
在prepare 方法中,对此 ThreadLocal 方法赋值:
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed));}
在myLooper 中会取出 此 ThreadLocal 中的 looper 对象:
public static Looper myLooper() { return sThreadLocal.get();}
但是突然有一天见到一个诡异的异常:
java.lang.ClassCastException: java.lang.StringBuilder cannot be cast to android.os.Looper at android.os.Looper.myLooper(Looper.java:249) at android.database.sqlite.SQLiteDatabase.isMainThread(SQLiteDatabase.java:404) at android.database.sqlite.SQLiteDatabase.getThreadDefaultConnectionFlags(SQLiteDatabase.java:395) at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59) at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31) at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1024) at com.android.providers.contacts.LegacyApiSupport.<init>(LegacyApiSupport.java:532) at com.android.providers.contacts.ContactsProvider2.initForDefaultLocale(ContactsProvider2.java:1930) at com.android.providers.contacts.ContactsProvider2.performBackgroundTask(ContactsProvider2.java:2055) at com.android.providers.contacts.ContactsProvider2$1.handleMessage(ContactsProvider2.java:12238) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:207) at android.os.HandlerThread.run(HandlerThread.java:61)
ThreadLocal 里面被存入了一个 StringBuilder ,然后在myLooper 中取出时发生了异常,先不说是谁能干出这档子事,先探究一下他是怎么存进去的:
范型是 存在于代码编译期,在生成字节码时,编译器会将范型去除,做类型擦除,
所以在ThreadLocal 中存入一个StringBuilder 只有可能在运行时完成,我所知道,能在运行时完成这件事的只有 反射了:
Field field = Looper.class.getDeclaredField("sThreadLocal");field.setAccessible(true);ThreadLocal sThreadLocal = ThreadLocal.class.cast(field.get(null));Method method = ThreadLocal.class.getMethod("set", Object.class);method.invoke(sThreadLocal, new StringBuilder());
如果使用这种方法,一般也不需要处理,可是本次发生的问题,是属于系统级apk的,并且系统源码里面没有找到此类的调用,哎,很是 奇怪啊,最后迫于无奈,在ThreadLocal 类的 set 方法里面添加了一下类型判断:
public void set(T value) { T oldValue = get(); if(oldValue != null && value != null && !((oldValue.getClass()).equals(value.getClass()))){ throw new RuntimeException(); } Thread currentThread = Thread.currentThread(); Values values = values(currentThread); if (values == null) { values = initializeValues(currentThread); } values.put(this, value);}
以此来规避,反射调用此方法,产生的异常。
阅读全文
0 0
- 范型&&诡异异常
- javamail诡异的504异常
- mybatis诡异的异常!!!时好时坏!!!
- Hibernate 的一个诡异的异常
- 传智播客学习之tomcat诡异异常
- java调用存储过程报诡异异常
- 诡异的java.lang.IllegalMonitorStateException异常
- 诡异
- 诡异
- 诡异
- oracle中存储过程、函数的诡异异常(错误)
- lua退出时内存删除的诡异异常及处理
- 关于LINQ语句的一个诡异的空异常
- Jenkins 新建maven项目svn报诡异异常
- 异常最诡异第二期之 Jedis pool.returnResource(jedis)
- 诡异的异常SEVERE: Error creating form bean of class
- 启动maven nexus3时遇到的"诡异"异常
- iframe结合ajax,诡异的多次访问方法异常
- 我们该如何理解卷积?
- Linux网络编程--使用epoll模型同时处理tcp和udp服务
- ACM大作业~~
- Mybatis Mapper动态代理方法 即 只写Dao接口 不谢Dao的实现类
- 数据库尽量不用字符串存储非字符串数据
- 范型&&诡异异常
- com.huawei.lcagent.client.LogCollectManager.getUserType
- Android 商品广告轮播图 图片轮播
- ffmpeg在centos7上的编译
- android studio:打jar包、apk包
- 问句相似度
- js跨域
- supervisor——配置文件详解
- mysql高并发配置