Gson使用泛型
如果你的后端统一了返回结果的话, 那么可以用Gson解析带泛型成员的Bean, 但在这个过程中遇到了一个坑, 现记录如下:
// 返回结果格式如下 public class Result<T> { private int code; private String message; private T data; // 省略getter和setter ... }
原来的实现是这样的:
public static <T> Result<T> fromJson(String json, Class<T> clazz) { Gson gson = new Gson(); Type type = new TypeToken<Result<T>>(){}.getType(); return gson.fromJson(json, type); }
但是上面的代码有问题, 在调试时发现data不会正常转化, 似乎是T失去了作用.
经查阅资料, 最后发现了原因和解决方案: https://www.jianshu.com/p/d62c2be60617
这是因为Java是泛型擦除的, 不像C++, 运行时是无法获得T的具体类型的, 所以自然就把data当成Object了. 因此, 我们只要手动把T的类型告诉Gson即可, 这里用了ParameterizedType
这个接口, 详情请看上面的文章.
private static class ParameterizedTypeImpl implements ParameterizedType { private final Class<?> raw; private final Type[] args; public ParameterizedTypeImpl(Class<?> raw, Type... args) { this.raw = raw; this.args = args != null ? args : new Type[0]; } @NonNull @Override public Type[] getActualTypeArguments() { return args; } @NonNull @Override public Type getRawType() { return raw; } @Override public Type getOwnerType() { return null; } } public static <T> Result<T> fromJson(String json, Class<T> clazz) { Gson gson = new Gson(); Type type = new ParameterizedTypeImpl(Result.class, clazz); return gson.fromJson(json, type); }
这样就没有问题啦~( •̀ ω •́ )✧
org.json如何判断null
在org.json中null被视为一个独特的类型(org.json.JSONObject#NULL
), 它重载了toString方法并且返回”null”, 所以直接用getString只会得到”null”. 应该调用org.json.JSONObject#isNull(String)
判断是否为空
Cannot add the same observer with different lifecycles
如果Lambda表达式中不使用外部变量或方法, 那么编译器会进行单例优化, 所以重复观察时使用了同一个observer对象, 导致此异常的发生.
解决方法也很简单:
- 不使用Lambda表达式, 把Lambda表达式里的代码抽到内部类中
- Lambda表达式内使用外部的非静态变量或方法
我选择第二种
参考自: https://juejin.cn/post/6934606974239637511
Android 9.0后在应用中使用http
从Android 9开始, 谷歌为安全起见, 应用默认是无法发起http请求的, 如果需要发送http请求, 需要在清单文件里进行配置:
第一种方式:
在清单文件的application
标签中添加属性android:usesCleartextTraffic="true"
第二种方式:
在res目录下创建xml目录, 然后在里面新建network_security_config.xml, 写入以下内容:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>
然后再在清单文件的application
标签中添加属性android:networkSecurityConfig="@xml/network_security_config"
推荐第二种方式, 但是更推荐使用https
在Room库中删除符合指定条件的行
Room的@Delete
注解只能删除指定的Entity, 若想根据条件删除可以用@Query
然后在里面写自定义查询语句(神奇吧
@Query("DELETE FROM user WHERE id = :id") void deleteById(int id);
ListView#setOnItemSelectedListener(AdapterView.OnItemSelectedListener)无效
在网上搜了一圈, 这个Listener好像只在焦点改变的时候才调用, 如果想监听选项点击应该用setOnItemClickListener
这里有详细的分析: https://www.jianshu.com/p/d11f86051c20
当然了, 能用RecyclerView就更好了
TextView中的超链接无法点击
需要调用TextView#setMovementMethod(LinkMovementMethod.getInstance())