SpannableSerializer { public static String serializeSpannableString(final SpannableString ss) { val json = new JSONObject(); try { json.put("mText", ss.toString()); json.put("bgc", extractClass(ss, BackgroundColorSpan.class)); json.put("fgc", extractClass(ss, ForegroundColorSpan.class)); } catch (JSONException e) { } return json.toString(); }  static String serializeSpannableString(final SpannableString ss); static SpannableString unserializeSpannableString(final String str);  }
@Test public void serializeSpannableStringTest() { val span = Span.colorSpan("abc", Color.RED); span.setSpan(new ForegroundColorSpan(Color.GREEN), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); val result = serializeSpannableString(span); assertWithMessage("span serialize template 1").that(result).isEqualTo("{\"mText\":\" abc \",\"bgc\":[{\"c\":-65536,\"s\":0,\"e\":5}],\"fgc\":[{\"c\":-16711936,\"s\":1,\"e\":2}]}"); val reformedResult = serializeSpannableString(unserializeSpannableString(serializeSpannableString(span))); assertWithMessage("span serialize reformed matches").that(reformedResult).isEqualTo(result); }