首页 文章 精选 留言 我的

精选列表

搜索[bug],共10000篇文章
优秀的个人博客,低调大师

微软Edge浏览器的这个bug可能让攻击者窃取你的任意信息

当你正在享受微软Edge浏览器内置的网页翻译功能时,可能触发恶意代码攻击。 微软上周推出了Edge浏览器更新,修复了两个安全问题。其中一个就是利用网页翻译功能发起攻击,它可以在网站代码中注入和执行任意代码。 该漏洞被追踪为CVE-2021-34506(CVSS评分:5.4),源于一个通用的跨网站脚本(UXSS)问题,该问题会在使用Edge浏览器内置的自动翻译网页功能时被触发。 该漏洞的发现者是Ignacio Laurence以及CyberXplore公司的Vansh Devgan和Shivam Kumar Singh。 "与常见的XSS攻击不同,UXSS是一种利用浏览器或浏览器扩展中的客户端漏洞以产生XSS条件,并执行恶意代码攻击,"CyberXplore研究人员表示。“当该漏洞被利用时,会绕过或禁用浏览器的安全功能。” 研究人员发现,翻译功能中的一段代码没有清洁输入,导致攻击者可以在网页任意地方插入恶意JavaScript,一旦用户点击地址栏的翻译提示按钮,就会执行该代码。 作为一个概念验证(PoC)漏洞,研究人员证明,只需在YouTube视频中添加一个非英文编写的注解和一个XSS有效载荷,就可以触发攻击。 同样,该漏洞还可以被应用在Facebook场景中,它可以藏匿在Facebook用户发送的好友请求中,包含非英文编写的注解和XSS有效载荷,一旦请求的接收者查看了该用户的个人资料,就会执行代码。 在6月3日披露之后,微软在6月24日(版本91.0.864.59)修复了该问题。此外,作为其漏洞赏金计划的一部分,微软还向研究人员奖励了2万美元。

优秀的个人博客,低调大师

分享一个新出炉的JVM里不痛不痒的BUG(Attach机制相关)

本文来自: PerfMa技术社区 PerfMa(笨马网络)官网 概述 老早之前写过一篇文章,关于attach机制的,可以看下这篇老文章了解一下JVM源码分析之Attach机制实现完全解读,比如大家常用的jstack,jmap等工具的主要原理都和attach机制有关,在JVM里处理这些命令的线程主要是Attach Listener这个线程,这个线程在JVM里是唯一的,我之前也一直以为是唯一的,但是我们同事最近在做一个线程分析产品的时候,发现我们抓到了多个Attach Listener线程,这让我也很疑惑,我第一感觉是不可能,肯定是数据抓错了,直到亲眼看到了两个同名的Attach Listener线程我才不得不相信原来还真有这种情况。 问题分析 不过从Attach Listener的实现来看,它设计的初衷不应该是一个多线程的设计,于是我昨晚上又翻了一遍代码,发现还真可能存在这种情况。举个栗子,当我们很多人同时执行jstack的时候,就可能会发生,当然有个前提是之前都没有做过任何和attach相关的操作。 Attach Listener线程默认情况下不会在JVM启动的时候就创建,当然也有一个JVM参数可以指定在JVM启动的时候就启动这个线程,这个就不会存在我们今天讨论的这个问题了,这个JVM参数是-XX:+StartAttachListener。 当我们在运行时触发attach机制的时候,首先会通过Signal Dispatcher线程来创建Attach Listener线程,代码如下: 在上面的圈起来的init方法里会创建Attach Listener线程,但是在init方法执行之前会通过_initialized属性来判断是否需要创建线程,而_initialized设置为true是在attach_listener_thread_entry里,这个是Attach Listener Thread的entry,也就是当这个线程执行的时候执行的方法。 但是在设置_initialized=true之前,如果有多个请求信号发出了(比如同时又很多jstack命令触发),可能会创建多个Attach Listener,因为Signal Dispatcher和Attach Listener线程是异步执行的。 问题复现 为了让效果更明显,我们可以在hotspot里修改下代码重新编译下再跑demo 在上面函数里加上圈起来的这段代码,表示在设置_initialized属性之前停留15s,当进程起来之后,不断执行jstack <pid>,最终将会看到有非常多的Attach Listener线程 其实问题的根本就是有一个空档期(设置_initialized为true之前)可能存在多次创建线程的可能。 总结 总的来说,创建Attach Listener线程是通过Signal Dispatcher线程来创建的,但是决定Signal Dispatcher是否可以重复创建Attach Listener线程的标记是在某个Attach Listener线程里设置的,如果没有及时设置该标记,就可能存在创建多个Attach Listener线程的情况。 一起来学习吧: PerfMa KO 系列课之 JVM 参数【Memory篇】 实战:一次疑似内存泄漏的问题排查

优秀的个人博客,低调大师

TypeScript 中让人头疼的 'as const' 与类型收窄陷阱:从一次线上 bug 说起

最近在维护一个数据看板项目时,遇到一个 TypeScript 类型报错,当时觉得明明逻辑没问题,编译却过不去。场景很简单:一个函数根据传入的字符串字面量决定返回不同的配置对象,但在 switch 分支里 TypeScript 死活不认已经收窄的类型,反而把整个联合类型都报出来。排查后发现根源在于 `as const` 的使用方式以及接口定义时没有正确保留字面量类型。这篇文章会从实际代码出发,梳理 `as const` 对推断的影响、类型收窄在哪些情况下会失效,以及如何用可辨识联合修复这类问题,顺带聊一下 `satisfies` 操作符在保持类型安全的同时避免过度断言。如果你也写过类似 `const config = { a: 1 } as const` 的代码,但没完全搞懂类型收窄为何有时候不生效,可以看看下面的详细拆解。 先看一段简化后的真实代码: ```ts interface Action { type: string; payload?: unknown; } function handleAction(action: Action) { switch (action.type) { case 'add': // 这里 action.payload 依然是 unknown // 但业务上我们希望它是 number console.log(action.payload + 1); // 报错:对象可能为 unknown break; case 'delete': console.log(action.payload); break; } } ``` 这段代码编译不通过,因为 `Action` 接口里 `type` 只是 `string`,TypeScript 无法根据 `case 'add'` 去推断 `payload` 的具体类型。很多人第一反应是把 `Action` 改成可辨识联合: ```ts type Action = | { type: 'add'; payload: number } | { type: 'delete'; payload: string }; ``` 改完确实能收窄了,但项目里常常会有另一个坑:当你从某个对象数组里读取数据时,如果不加 `as const`,`type` 会被推断成 `string`,导致联合类型失效。 ```ts const actions = [ { type: 'add', payload: 1 }, { type: 'delete', payload: 'id' }, ]; // actions 的类型是 { type: string; payload: number | string }[] ``` 这时候 `actions[0].type` 只是 `string`,传给 `handleAction` 时无法匹配可辨识联合,报错就来了。加上 `as const` 能解决: ```ts const actions = [ { type: 'add', payload: 1 }, { type: 'delete', payload: 'id' }, ] as const; // 每个元素的 type 变成字面量 'add' | 'delete' ``` 但 `as const` 也会带来新问题:整个对象变成 readonly,如果后续代码需要修改 `payload`,类型系统就会阻止你。这时候可以用 `satisfies` 来约束类型,同时保留字面量推断: ```ts type Action = | { type: 'add'; payload: number } | { type: 'delete'; payload: string }; const actions = [ { type: 'add', payload: 1 }, { type: 'delete', payload: 'id' }, ] satisfies Action[]; ``` 这样 `actions` 的元素类型依然是字面量联合,且没有被 readonly 锁死。不过 `satisfies` 要求 TypeScript 4.9 以上,老项目升级时要注意。 另一个常见误用是在函数参数里写 `as const`: ```ts function logType(type: 'add' | 'delete') {} const t = 'add' as const; logType(t); // 正确 let t2 = 'add'; logType(t2 as const); // 也能过,但 t2 本身还是 string ``` `as const` 只是断言,不会改变变量原本的类型声明。如果变量是 `let` 或者来自外部 API,最好用类型守卫或显式类型注解。 还有个容易忽略的点:解构赋值时字面量类型会丢失。 ```ts const action = { type: 'add', payload: 1 } as const; const { type } = action; // type 的类型是 'add',没问题 function getAction() { return { type: 'add', payload: 1 } as const; } const { type } = getAction(); // type 仍然是 'add' ``` 但如果中间经过一次展开或者对象合并,`as const` 的效果可能被稀释: ```ts const base = { type: 'add' } as const; const merged = { ...base, payload: 1 }; // merged.type 变成 string,因为展开操作会拓宽类型 ``` 要修复可以显式注解 `merged` 的类型,或者用 `as const` 包裹整个合并结果。 实际项目里,我现在的习惯是:对于固定配置表、常量映射,一律用 `as const` 配合 `satisfies`;对于函数参数和返回值,尽量用可辨识联合和类型谓词,而不是依赖断言。比如下面这个类型守卫: ```ts function isAddAction(action: Action): action is Extract { return action.type === 'add'; } ``` `Extract` 能准确提取出联合类型中的分支,比手写接口更安全。 最后提一下 `enum` 与 `as const` 的选择。很多人喜欢用 `enum` 定义一组常量,但 `enum` 编译后会产生真实对象,且类型收窄行为有时不如字面量联合直观。用 `as const` 定义常量对象更轻量: ```ts export const ActionTypes = { Add: 'add', Delete: 'delete', } as const; export type ActionType = typeof ActionTypes[keyof typeof ActionTypes]; // 'add' | 'delete' ``` 这样既能在运行时遍历,也能在类型层面收窄,还不增加额外运行时代码。 这些细节在写业务代码时经常一闪而过,但一旦遇到类型报错,理解 `as const` 和收窄的边界能省下不少调试时间。 推荐查看天气:https://www.40tianqi.com/qianan/7tian.html 推荐查看天气:https://www.40tianqi.com/qianan/10tian.html 推荐查看天气:https://www.40tianqi.com/qianan/15tian.html 推荐查看天气:https://www.40tianqi.com/qianan/40tian.html 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/ 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/zuotian.html 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/7tian.html 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/10tian.html 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/15tian.html 推荐查看天气:https://www.40tianqi.com/songyuanfuyu/40tian.html 推荐查看天气:https://www.40tianqi.com/yanbian/ 推荐查看天气:https://www.40tianqi.com/yanbian/zuotian.html 推荐查看天气:https://www.40tianqi.com/yanbian/7tian.html 推荐查看天气:https://www.40tianqi.com/yanbian/10tian.html 推荐查看天气:https://www.40tianqi.com/yanbian/15tian.html 推荐查看天气:https://www.40tianqi.com/yanbian/40tian.html 推荐查看天气:https://www.40tianqi.com/yanji/ 推荐查看天气:https://www.40tianqi.com/yanji/zuotian.html 推荐查看天气:https://www.40tianqi.com/yanji/7tian.html 推荐查看天气:https://www.40tianqi.com/yanji/10tian.html 推荐查看天气:https://www.40tianqi.com/yanji/15tian.html 推荐查看天气:https://www.40tianqi.com/yanji/40tian.html 推荐查看天气:https://www.40tianqi.com/tumen/ 推荐查看天气:https://www.40tianqi.com/tumen/zuotian.html 推荐查看天气:https://www.40tianqi.com/tumen/7tian.html 推荐查看天气:https://www.40tianqi.com/tumen/10tian.html 推荐查看天气:https://www.40tianqi.com/tumen/15tian.html 推荐查看天气:https://www.40tianqi.com/tumen/40tian.html 推荐查看天气:https://www.40tianqi.com/dunhua/ 推荐查看天气:https://www.40tianqi.com/dunhua/zuotian.html 推荐查看天气:https://www.40tianqi.com/dunhua/7tian.html 推荐查看天气:https://www.40tianqi.com/dunhua/10tian.html 推荐查看天气:https://www.40tianqi.com/dunhua/15tian.html 推荐查看天气:https://www.40tianqi.com/dunhua/40tian.html 推荐查看天气:https://www.40tianqi.com/huichun/ 推荐查看天气:https://www.40tianqi.com/huichun/zuotian.html 推荐查看天气:https://www.40tianqi.com/huichun/7tian.html 推荐查看天气:https://www.40tianqi.com/huichun/10tian.html 推荐查看天气:https://www.40tianqi.com/huichun/15tian.html 推荐查看天气:https://www.40tianqi.com/huichun/40tian.html 推荐查看天气:https://www.40tianqi.com/longjing/ 推荐查看天气:https://www.40tianqi.com/longjing/zuotian.html 推荐查看天气:https://www.40tianqi.com/longjing/7tian.html 推荐查看天气:https://www.40tianqi.com/longjing/10tian.html 推荐查看天气:https://www.40tianqi.com/longjing/15tian.html 推荐查看天气:https://www.40tianqi.com/longjing/40tian.html 推荐查看天气:https://www.40tianqi.com/helong/ 推荐查看天气:https://www.40tianqi.com/helong/zuotian.html 推荐查看天气:https://www.40tianqi.com/helong/7tian.html 推荐查看天气:https://www.40tianqi.com/helong/10tian.html 推荐查看天气:https://www.40tianqi.com/helong/15tian.html 推荐查看天气:https://www.40tianqi.com/helong/40tian.html 推荐查看天气:https://www.40tianqi.com/wangqing/ 推荐查看天气:https://www.40tianqi.com/wangqing/zuotian.html 推荐查看天气:https://www.40tianqi.com/wangqing/7tian.html 推荐查看天气:https://www.40tianqi.com/wangqing/10tian.html 推荐查看天气:https://www.40tianqi.com/wangqing/15tian.html 推荐查看天气:https://www.40tianqi.com/wangqing/40tian.html 推荐查看天气:https://www.40tianqi.com/antu/ 推荐查看天气:https://www.40tianqi.com/antu/zuotian.html 推荐查看天气:https://www.40tianqi.com/antu/7tian.html 推荐查看天气:https://www.40tianqi.com/antu/10tian.html 推荐查看天气:https://www.40tianqi.com/antu/15tian.html 推荐查看天气:https://www.40tianqi.com/antu/40tian.html 推荐查看天气:https://www.40tianqi.com/haerbin/ 推荐查看天气:https://www.40tianqi.com/haerbin/zuotian.html 推荐查看天气:https://www.40tianqi.com/haerbin/7tian.html 推荐查看天气:https://www.40tianqi.com/haerbin/10tian.html 推荐查看天气:https://www.40tianqi.com/haerbin/15tian.html 推荐查看天气:https://www.40tianqi.com/haerbin/40tian.html 推荐查看天气:https://www.40tianqi.com/daoli/ 推荐查看天气:https://www.40tianqi.com/daoli/zuotian.html 推荐查看天气:https://www.40tianqi.com/daoli/7tian.html 推荐查看天气:https://www.40tianqi.com/daoli/10tian.html 推荐查看天气:https://www.40tianqi.com/daoli/15tian.html 推荐查看天气:https://www.40tianqi.com/daoli/40tian.html 推荐查看天气:https://www.40tianqi.com/nangang/ 推荐查看天气:https://www.40tianqi.com/nangang/zuotian.html 推荐查看天气:https://www.40tianqi.com/nangang/7tian.html 推荐查看天气:https://www.40tianqi.com/nangang/10tian.html 推荐查看天气:https://www.40tianqi.com/nangang/15tian.html 推荐查看天气:https://www.40tianqi.com/nangang/40tian.html 推荐查看天气:https://www.40tianqi.com/daowai/ 推荐查看天气:https://www.40tianqi.com/daowai/zuotian.html 推荐查看天气:https://www.40tianqi.com/daowai/7tian.html 推荐查看天气:https://www.40tianqi.com/daowai/10tian.html 推荐查看天气:https://www.40tianqi.com/daowai/15tian.html 推荐查看天气:https://www.40tianqi.com/daowai/40tian.html 推荐查看天气:https://www.40tianqi.com/pingfang/ 推荐查看天气:https://www.40tianqi.com/pingfang/zuotian.html 推荐查看天气:https://www.40tianqi.com/pingfang/7tian.html 推荐查看天气:https://www.40tianqi.com/pingfang/10tian.html 推荐查看天气:https://www.40tianqi.com/pingfang/15tian.html 推荐查看天气:https://www.40tianqi.com/pingfang/40tian.html 推荐查看天气:https://www.40tianqi.com/songbei/ 推荐查看天气:https://www.40tianqi.com/songbei/zuotian.html 推荐查看天气:https://www.40tianqi.com/songbei/7tian.html 推荐查看天气:https://www.40tianqi.com/songbei/10tian.html 推荐查看天气:https://www.40tianqi.com/songbei/15tian.html 推荐查看天气:https://www.40tianqi.com/songbei/40tian.html 推荐查看天气:https://www.40tianqi.com/xiangfang/ 推荐查看天气:https://www.40tianqi.com/xiangfang/zuotian.html 推荐查看天气:https://www.40tianqi.com/xiangfang/7tian.html 推荐查看天气:https://www.40tianqi.com/xiangfang/10tian.html 推荐查看天气:https://www.40tianqi.com/xiangfang/15tian.html 推荐查看天气:https://www.40tianqi.com/xiangfang/40tian.html 推荐查看天气:https://www.40tianqi.com/hulan/ 推荐查看天气:https://www.40tianqi.com/hulan/zuotian.html 推荐查看天气:https://www.40tianqi.com/hulan/7tian.html 推荐查看天气:https://www.40tianqi.com/hulan/10tian.html 推荐查看天气:https://www.40tianqi.com/hulan/15tian.html 推荐查看天气:https://www.40tianqi.com/hulan/40tian.html 推荐查看天气:https://www.40tianqi.com/acheng/ 推荐查看天气:https://www.40tianqi.com/acheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/acheng/7tian.html 推荐查看天气:https://www.40tianqi.com/acheng/10tian.html 推荐查看天气:https://www.40tianqi.com/acheng/15tian.html 推荐查看天气:https://www.40tianqi.com/acheng/40tian.html 推荐查看天气:https://www.40tianqi.com/haerbinyilan/ 推荐查看天气:https://www.40tianqi.com/haerbinyilan/zuotian.html 推荐查看天气:https://www.40tianqi.com/haerbinyilan/7tian.html 推荐查看天气:https://www.40tianqi.com/haerbinyilan/10tian.html 推荐查看天气:https://www.40tianqi.com/haerbinyilan/15tian.html 推荐查看天气:https://www.40tianqi.com/haerbinyilan/40tian.html 推荐查看天气:https://www.40tianqi.com/fangzheng/ 推荐查看天气:https://www.40tianqi.com/fangzheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/fangzheng/7tian.html 推荐查看天气:https://www.40tianqi.com/fangzheng/10tian.html 推荐查看天气:https://www.40tianqi.com/fangzheng/15tian.html 推荐查看天气:https://www.40tianqi.com/fangzheng/40tian.html 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/ 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/zuotian.html 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/7tian.html 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/10tian.html 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/15tian.html 推荐查看天气:https://www.40tianqi.com/haerbinbinxian/40tian.html 推荐查看天气:https://www.40tianqi.com/bayan/ 推荐查看天气:https://www.40tianqi.com/bayan/zuotian.html 推荐查看天气:https://www.40tianqi.com/bayan/7tian.html 推荐查看天气:https://www.40tianqi.com/bayan/10tian.html 推荐查看天气:https://www.40tianqi.com/bayan/15tian.html 推荐查看天气:https://www.40tianqi.com/bayan/40tian.html 推荐查看天气:https://www.40tianqi.com/mulan/ 推荐查看天气:https://www.40tianqi.com/mulan/zuotian.html 推荐查看天气:https://www.40tianqi.com/mulan/7tian.html 推荐查看天气:https://www.40tianqi.com/mulan/10tian.html 推荐查看天气:https://www.40tianqi.com/mulan/15tian.html 推荐查看天气:https://www.40tianqi.com/mulan/40tian.html 推荐查看天气:https://www.40tianqi.com/tonghe/ 推荐查看天气:https://www.40tianqi.com/tonghe/zuotian.html 推荐查看天气:https://www.40tianqi.com/tonghe/7tian.html 推荐查看天气:https://www.40tianqi.com/tonghe/10tian.html 推荐查看天气:https://www.40tianqi.com/tonghe/15tian.html 推荐查看天气:https://www.40tianqi.com/tonghe/40tian.html 推荐查看天气:https://www.40tianqi.com/yanshou/ 推荐查看天气:https://www.40tianqi.com/yanshou/zuotian.html 推荐查看天气:https://www.40tianqi.com/yanshou/7tian.html 推荐查看天气:https://www.40tianqi.com/yanshou/10tian.html 推荐查看天气:https://www.40tianqi.com/yanshou/15tian.html 推荐查看天气:https://www.40tianqi.com/yanshou/40tian.html 推荐查看天气:https://www.40tianqi.com/shangzhi/ 推荐查看天气:https://www.40tianqi.com/shangzhi/zuotian.html 推荐查看天气:https://www.40tianqi.com/shangzhi/7tian.html 推荐查看天气:https://www.40tianqi.com/shangzhi/10tian.html 推荐查看天气:https://www.40tianqi.com/shangzhi/15tian.html 推荐查看天气:https://www.40tianqi.com/shangzhi/40tian.html 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/ 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/zuotian.html 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/7tian.html 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/10tian.html 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/15tian.html 推荐查看天气:https://www.40tianqi.com/haerbinwuchang/40tian.html 推荐查看天气:https://www.40tianqi.com/qiqihaer/ 推荐查看天气:https://www.40tianqi.com/qiqihaer/zuotian.html 推荐查看天气:https://www.40tianqi.com/qiqihaer/7tian.html 推荐查看天气:https://www.40tianqi.com/qiqihaer/10tian.html 推荐查看天气:https://www.40tianqi.com/qiqihaer/15tian.html 推荐查看天气:https://www.40tianqi.com/qiqihaer/40tian.html 推荐查看天气:https://www.40tianqi.com/longsha/ 推荐查看天气:https://www.40tianqi.com/longsha/zuotian.html 推荐查看天气:https://www.40tianqi.com/longsha/7tian.html 推荐查看天气:https://www.40tianqi.com/longsha/10tian.html 推荐查看天气:https://www.40tianqi.com/longsha/15tian.html 推荐查看天气:https://www.40tianqi.com/longsha/40tian.html 推荐查看天气:https://www.40tianqi.com/jianhua/ 推荐查看天气:https://www.40tianqi.com/jianhua/zuotian.html 推荐查看天气:https://www.40tianqi.com/jianhua/7tian.html 推荐查看天气:https://www.40tianqi.com/jianhua/10tian.html 推荐查看天气:https://www.40tianqi.com/jianhua/15tian.html 推荐查看天气:https://www.40tianqi.com/jianhua/40tian.html 推荐查看天气:https://www.40tianqi.com/tiefeng/ 推荐查看天气:https://www.40tianqi.com/tiefeng/zuotian.html 推荐查看天气:https://www.40tianqi.com/tiefeng/7tian.html 推荐查看天气:https://www.40tianqi.com/tiefeng/10tian.html 推荐查看天气:https://www.40tianqi.com/tiefeng/15tian.html 推荐查看天气:https://www.40tianqi.com/tiefeng/40tian.html 推荐查看天气:https://www.40tianqi.com/angangxi/ 推荐查看天气:https://www.40tianqi.com/angangxi/zuotian.html 推荐查看天气:https://www.40tianqi.com/angangxi/7tian.html 推荐查看天气:https://www.40tianqi.com/angangxi/10tian.html

优秀的个人博客,低调大师

是ActivityGroup 的BUG?是对机制理解不深刻?还是逻辑错误?还是。。。不知道了?

首先,先喷一下张艺谋的片子,你他妈太黑了~!什么史上最干净的爱情片,我说是史上最烂的爱情片,只能把无知当纯情。拍电影拍得一点诚意都没有,只会抄韩国的爱情片,记得有一部韩国片跟你这部剧情都差不多~!你就使劲抄吧~!!浪费我160大洋,进去睡觉。 喷到这里。 这一两天碰到一个问题,是一个关于ActivityGroup 的问题,因为项目需要,必须把一个自定义的PreferenceActivity 的界面嵌套在ActivityGroup 里面,可是当我嵌套在里面的时候发现了一个问题。就是PreferenceActivity 的元素不会自动更新UI,这是比较致命的,不知道为什么会出现这个问题。 查了很久,首先我怀疑是我的自定义preference写的有问题,改了一遍,然后再运行还是一样。 单独运行该 preferenceActivity 试了一下,界面可以按照自己的需求更新UI,那就是说不是我这个自定义的preference 的逻辑问题?这点还不敢确定。 那么我怀疑是 ActivityGroup 不允许底下Activity 元素的UI自动更新,那么新建一个普通的Activity 来试试,在这普通的Activity 里面只有一个按钮同样是点击之后弹出对话框然后改变按钮的字,试了一下,。更新成功。。。耶?那么说ActivityGroup 还是允许底下Activity UI 元素更新的?那么问题出在哪呢? 我又再调试跟踪了代码,确定有执行settext的代码?那是不是说preferenceActivity 和ActivityGroup有冲突?不知道所然,下面贴出我碰到问题的全部代码,由于在公司有加密软件无法将DEMO提供给大家,大家可以根据代码新建一个工程,一起来研究这个问题。 自定义的PreferenceScreenExt 源码: packageasai.cn.seekbardemo; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; importandroid.app.Dialog; importandroid.content.Context; importandroid.content.DialogInterface; importandroid.content.SharedPreferences; importandroid.preference.Preference; importandroid.preference.PreferenceGroup; importandroid.util.AttributeSet; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.view.View.OnClickListener; importandroid.widget.AdapterView; importandroid.widget.ListView; importandroid.widget.RelativeLayout; importandroid.widget.SimpleAdapter; importandroid.widget.TextView; importandroid.widget.AdapterView.OnItemClickListener; public class PreferenceScreenExtextendsPreferenceGroupimplements OnItemClickListener,DialogInterface.OnDismissListener{ private Dialogdialog; private TextViewtitle,summary; private SharedPreferencesshare; private RelativeLayoutarea; private ListViewlistView; List < Preference > list; private List < HashMap < String,String >> listStr; private CharSequence[]mEntries; private StringmValue; private SimpleAdaptersimple; public PreferenceScreenExt(Contextcontext,AttributeSetattrs){ this (context,attrs,android.R.attr.preferenceScreenStyle); // TODOAuto-generatedconstructorstub } public PreferenceScreenExt(Contextcontext,AttributeSetattrs, int defStyle){ super(context,attrs,android.R.attr.preferenceScreenStyle); // TODOAuto-generatedconstructorstub int resouceId = attrs.getAttributeResourceValue( null , " Entries " , 0 ); if (resouceId > 0 ){ mEntries = getContext().getResources().getTextArray(resouceId); } } @Override protected ViewonCreateView(ViewGroupparent){ // TODOAuto-generatedmethodstu Viewview = LayoutInflater.from(getContext()).inflate( R.layout.preference_screen, null ); area = (RelativeLayout)view.findViewById(R.id.area); share = getPreferenceManager().getSharedPreferences(); title = (TextView)view.findViewById(R.id.title); summary = (TextView)view.findViewById(R.id.summary); title.setText(getTitle()); summary.setText(share.getString(getKey(),getSummary() == null ? "" :getSummary().toString())); area.setOnClickListener( new OnClickListener(){ @Override public void onClick(Viewv){ // TODOAuto-generatedmethodstub showDialog(); } }); return view; } public void bindView(ListViewlistview){ int length = mEntries.length; int i = 0 ; listStr = new ArrayList < HashMap < String,String >> (); for (i = 0 ;i < length;i ++ ){ HashMap < String,String > map = new HashMap < String,String > (); map.put( " keyname " ,mEntries[i].toString()); listStr.add(map); } simple = new SimpleAdapter(getContext(),listStr,R.layout.dialog_view, new String[]{ " keyname " }, new int []{R.id.text}); listview.setAdapter(simple); listview.setOnItemClickListener( this ); } public void showDialog(){ listView = new ListView(getContext()); bindView(listView); dialog = new Dialog(getContext(),android.R.style.Theme_NoTitleBar); dialog.setContentView(listView); dialog.setOnDismissListener( this ); dialog.show(); } @Override public void onItemClick(AdapterView <?> parent,Viewview, int position, long id){ // TODOAuto-generatedmethodstub mValue = listStr. get (position). get ( " keyname " ).toString(); SharedPreferences.Editoreditor = getEditor(); editor.putString(getKey(),mValue); callChangeListener(mValue); PreferenceScreenExt. this .setOnPreferenceChangeListener( new OnPreferenceChangeListener(){ @Override public booleanonPreferenceChange(Preferencepreference, ObjectnewValue){ // TODOAuto-generatedmethodstub if (temp != null ){ temp.onPreferenceChange(PreferenceScreenExt. this , newValue); } return true ; } }); editor.commit(); dialog.dismiss(); } @Override public void onDismiss(DialogInterfacedialog){ // TODOAuto-generatedmethodstub } private OnPreferenceChangeListenertemp; public interface OnPreferenceChangeListener{ public booleanonPreferenceChange(Preferencepreference,ObjectnewValue); } public void setOnPreferenceChangeListener( OnPreferenceChangeListenerpreference){ this .temp = preference; } public void setValue(Stringvalue){ summary.setText(value); persistString(value); } } 对应的XML布局文件: dialog_view.xml <? xmlversion="1.0"encoding="utf-8" ?> < LinearLayout android:layout_width ="fill_parent" xmlns:android ="http://schemas.android.com/apk/res/android" android:orientation ="vertical" android:gravity ="center" android:layout_height ="fill_parent" > < TextView android:id ="@+id/text" android:layout_marginLeft ="20dp" android:textAppearance ="?android:attr/textAppearanceLarge" android:textSize ="35sp" android:layout_width ="wrap_content" android:layout_height ="wrap_content" > </ TextView > </ LinearLayout > preference_screen.xml <? xmlversion="1.0"encoding="utf-8" ?> < RelativeLayout android:id ="@+id/area" android:gravity ="center_vertical" android:layout_marginTop ="5px" android:clickable ="true" xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="fill_parent" android:layout_height ="wrap_content" > < TextView android:id ="@+id/title" android:layout_marginLeft ="20dp" android:textAppearance ="?android:attr/textAppearanceLarge" android:textSize ="35sp" android:layout_width ="wrap_content" android:layout_height ="wrap_content" > </ TextView > < TextView android:id ="@+id/summary" android:layout_marginRight ="20dp" android:textSize ="35sp" android:textAppearance ="?android:attr/textAppearanceLarge" android:layout_alignParentRight ="true" android:layout_width ="wrap_content" android:layout_height ="wrap_content" > </ TextView > </ RelativeLayout > XML文件夹下的XML文件: preference.xml <? xmlversion="1.0"encoding="utf-8" ?> < PreferenceScreen xmlns:android ="http://schemas.android.com/apk/res/android" > < asai.cn.seekbardemo.PreferenceScreenExt Entries ="@array/country" android:title ="收音区域" android:summary ="美国" android:persistent ="true" android:key ="eeg" > </ asai.cn.seekbardemo.PreferenceScreenExt > </ PreferenceScreen > main.java 对应代码 packageasai.cn.seekbardemo; importandroid.app.ActivityGroup; importandroid.app.LocalActivityManager; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.Window; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.LinearLayout; public class mainextendsActivityGroupimplementsOnClickListener{ private LocalActivityManagerlm; private LinearLayoutlayout; private Buttonbtn,btn2; @Override protected void onCreate(BundlesavedInstanceState){ // TODOAuto-generatedmethodstub super.onCreate(savedInstanceState); setContentView(R.layout.group); lm = getLocalActivityManager(); btn = (Button)findViewById(R.id.Button01); btn2 = (Button)findViewById(R.id.Button02); btn.setOnClickListener( this ); btn2.setOnClickListener( this ); layout = (LinearLayout)findViewById(R.id.layout); Intentintent = new Intent( this ,seekBarDemo. class ); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Windoww = lm.startActivity( " test " ,intent); Viewv = w.getDecorView(); layout.removeAllViews(); layout.addView(v); } @Override public void onClick(Viewv){ // TODOAuto-generatedmethodstub switch (v.getId()){ case R.id.Button01: Intentintent = new Intent( this ,seekBarDemo. class ); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Windoww = lm.startActivity( " test " ,intent); Viewview = w.getDecorView(); layout.removeAllViews(); layout.addView(view); break ; case R.id.Button02: Intent in = new Intent( this ,test. class ); in .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Windowwin = lm.startActivity( " ww " , in ); Viewvw = win.getDecorView(); layout.removeAllViews(); layout.addView(vw); break ; default : break ; } } } 对应的XML布局文件: group.xml <? xmlversion="1.0"encoding="utf-8" ?> < LinearLayout android:orientation ="vertical" android:layout_width ="fill_parent" android:layout_height ="fill_parent" xmlns:android ="http://schemas.android.com/apk/res/android" > < LinearLayout android:layout_width ="fill_parent" android:gravity ="center_horizontal" android:layout_height ="wrap_content" > < Button android:text ="preference界面" android:id ="@+id/Button01" android:layout_width ="wrap_content" android:layout_height ="wrap_content" ></ Button > < Button android:text ="普通" android:id ="@+id/Button02" android:layout_width ="wrap_content" android:layout_height ="wrap_content" ></ Button > </ LinearLayout > < LinearLayout android:id ="@+id/layout" android:layout_width ="fill_parent" android:layout_height ="wrap_content" ></ LinearLayout > </ LinearLayout > PreferenceActivity 界面代码 SeekBarDemo.java: packageasai.cn.seekbardemo; importandroid.os.Bundle; importandroid.preference.Preference; importandroid.preference.PreferenceActivity; importandroid.preference.Preference.OnPreferenceChangeListener; importandroid.widget.TextView; public class seekBarDemoextendsPreferenceActivity{ private Preferenceeeg; /* *Calledwhentheactivityisfirstcreated. */ @Override public void onCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preference); finalPreferenceScreenExtpre = (PreferenceScreenExt)findPreference( " eeg " ); pre.setOnPreferenceChangeListener( new OnPreferenceChangeListener(){ @Override public booleanonPreferenceChange(Preferencepreference, ObjectnewValue){ // TODOAuto-generatedmethodstub pre.setValue(String.valueOf(newValue)); return true ; } }); } } 普通的Activity 界面代码test.java: packageasai.cn.seekbardemo; importandroid.app.Activity; importandroid.app.AlertDialog; importandroid.content.DialogInterface; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; public class testextendsActivity{ @Override protected void onCreate(BundlesavedInstanceState){ // TODOAuto-generatedmethodstub super.onCreate(savedInstanceState); setContentView(R.layout.test); finalButtonbtn = (Button)findViewById(R.id.Button01); btn.setOnClickListener( new OnClickListener(){ @Override public void onClick(Viewv){ // TODOAuto-generatedmethodstub new AlertDialog.Builder(test. this ).setMessage( " 修改 " ).setTitle( " 提示 " ).setPositiveButton(android.R. string .ok, new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterfacedialog, int which){ // TODOAuto-generatedmethodstub btn.setText( " 修改后的按钮 " ); } }).show(); } }); } } 配置文件: AndroidManifest.xml <? xmlversion="1.0"encoding="utf-8" ?> < manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="asai.cn.seekbardemo" android:versionCode ="1" android:versionName ="1.0" > < application android:icon ="@drawable/icon" android:label ="@string/app_name" > < activity android:name =".main" android:label ="@string/app_name" > < intent-filter > < action android:name ="android.intent.action.MAIN" /> < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < activity android:name =".test" android:label ="@string/app_name" > < intent-filter > < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < activity android:name =".seekBarDemo" android:label ="@string/app_name" > < intent-filter > < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > </ application > < uses-sdk android:minSdkVersion ="7" /> </ manifest > 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/397862,如需转载请自行联系原作者

资源下载

更多资源
Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册