Java/Android中String.contains方法失效问题求助(SpannableString场景)
问题根因分析
1. 核心问题:contains匹配逻辑存在子串误判
你需要判断缓存的spot文本是否和传入的lit1、lit2匹配,但contains(a+"/"+b)仅能判断子串是否存在,极易出现误判:
当缓存的spot文本为Spotted 200/300 lights时,若传入lit1=0、lit2=300,拼接的匹配串是0/300,原文本中的200/300天然包含0/300这个子串,导致!spot.toString().contains(a+"/"+b)条件返回false,不会触发更新逻辑,直接返回旧缓存内容,这就是你遇到的问题的本质原因。
2. 代码笔误:变量引用错误
你已经将lit1转为字符串a,但拼接SpannableString时错误使用了未知变量d:
// 错误写法 spot = new SpannableString("Spotted "+d+"/"+b+" lights"); // 正确写法应为 spot = new SpannableString("Spotted "+a+"/"+b+" lights");
如果d是类中定义的其他静态变量,会导致拼接的数值永远是d的旧值,和传入的lit1完全无关。
3. Span范围计算错误
设置前景色Span的结束位置计算错误,漏了两个数值中间斜杠的1位长度:
// 错误写法:少算了斜杠的1个字符长度 spot.setSpan(y, 7, 7+d.length()+b.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
Spotted 末尾有空格,共8个字符,数字部分总长度是a的长度+1位斜杠+b的长度,所以Span结束位置应为8 + a.length() + 1 + b.length()。
4. 静态变量缓存风险
spot、y被定义为静态变量,全局唯一缓存,若存在多线程调用、多场景调用的需求,会出现变量互相覆盖的问题,建议根据业务场景判断是否需要取消静态修饰,或增加独立的缓存维度。
修复方案
直接改为判断传入参数是否和上次调用的参数一致,比字符串匹配效率更高、无歧义,修正后参考代码如下:
public class Span { // 缓存上次传入的参数,避免字符串匹配误判 private static int lastLit1 = -1; private static int lastLit2 = -1; private static SpannableString spot; private static ForegroundColorSpan y; public static SpannableString SPOT(int lit1, int lit2){ if(spot == null || lastLit1 != lit1 || lastLit2 != lit2){ String a = Integer.toString(lit1), b = Integer.toString(lit2); y = new ForegroundColorSpan(Color.YELLOW); String content = "Spotted " + a + "/" + b + " lights"; spot = new SpannableString(content); int start = "Spotted ".length(); int end = start + a.length() + 1 + b.length(); spot.setSpan(y, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); // 更新缓存参数 lastLit1 = lit1; lastLit2 = lit2; } return spot; } }
内容的提问来源于stack exchange,提问作者Phillip Us
相关产品推荐
相关产品推荐

