泛型单例模式Android Tips 是我平时收集了开发中遇到的问题,虽然都是一些小的知识点或技巧,但实际作用很大。Android Tips 是用 GitBook 写的,最终生成 PDF,售价 ¥ 10.24,购买链接见文末。我也已经将 Android Tips 大部分分享到了我的小密圈,可以加入我的小密圈,收获更多。今天分享的两个知识点我觉得用途很大,也分享到公众号上来。
单例模式在实际开发中应用很广,什么是单例模式,见博客:http://wuxiaolong.me/2017/01/02/singleton/ 。如果单例模式每个都要这样写,也是很麻烦的,我们发现每次就实例化的对象不一样,能不能做到只要改变这个实例化的对象,就能得要我们想要的单例昵,答案是肯定的,这里用到了泛型知识,1 + 1 > 2,体现了泛型的强大。
public class SingletonUtil {
/***
* 采用ConcurrentHashMap集合进行存储
* Class 作为key ---对象的类型
* Object 作为value---对象的实例化
* 实现对象的类型和对象的实例化 一一对应
*/
private static final ConcurrentMap<Class, Object> map = new ConcurrentHashMap<>();
/***
*
* @param type 传入进行实例化对象的类型
* @return T 即返回对象的实例化
*/
public static <T> T getSingleton(Class<T> type) {
/***
* 从map中取出对象的相对应的实例
*
* 为减少对map的操作,在此处使用局部变量ob --- 符合优化性能要求
*/
Object ob = map.get(type);
try {
/***
* 对该对象的实例进行null判断
*/
if (ob == null) {
/***
* 为使用安全的map及其操作 设置同步锁
*/
synchronized (map) {
/***
* 创建此 Class 对象所表示的类的一个新实例。
* 如同用一个带有一个空参数列表的 new 表达式实例化该类。
* 如果该类尚未初始化,则初始化这个类。
*/
ob = type.newInstance();
/***
* 将对象类型和创建的新实例放进map
*/
map.put(type, ob);
}
}
/***
* 是type.newInstance()产生的两个异常处理
*
*IllegalAccessException - 如果该类或其 null 构造方法是不可访问的。
*InstantiationException - 如果此 Class 表示一个抽象类、接口、数组类、
*基本类型或 void; 或者该类没有 null 构造方法; 或者由于其他某种原因导致实例化失败
*
*在此不做过多处理
*/
} catch (Exception e) {
e.printStackTrace();
}
/***
* 将从map中取出的对象的实例化 转换成泛型参数 返回
*/
return (T) ob;
}
/***
* 该方法 是从map中移除对象实例化操作
* @param type
*/
public static <T> void remove(Class<T> type) {
/***
* map移除操作
*/
map.remove(type);
}
}
调用:
public class Simple {
public void hello() {
//to do something
}
}
获得 Simple 单例,并调用其方法:
SingletonUtil.getSingleton(Simple.class).hello();观察者模式
A 页面跳到 B 页面,又从 B 页面跳到 C 页面,现在 C 页面变化,需要 A 页面和 B 页面同步变化,比如点赞数,怎么做昵?EventBus 能帮助我们做到这点,直接发通知,A、B 页面就可以做改变;当我知道RxBus 时,果断抛弃了 EventBus,因为项目正好是 Retrofit + RxJava。他们原理都使用了观察者模式,由于 Java 观察者模式更加简单,不需要依赖什么第三方库,我又果断抛弃了 RxBus,后来我项目中也对观察者模式做了简单封装:
1、BaseEvent
public class BaseEvent extends Observable {
public void post() {
setChanged();
//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
notifyObservers();
}
public void post(Object arg) {
setChanged();
//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
notifyObservers(arg);
}
}
2、OrderListHandleEvent
public class OrderListHandleEvent extends BaseEvent {
}
3、MyBookActivity(观察者)
public class MyBookActivity extends BaseActivity implements Observer {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.account_activity_my_book);
//订阅
SingletonUtil.getSingleton(OrderListHandleEvent.class).addObserver(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消订阅
SingletonUtil.getSingleton(OrderListHandleEvent.class).deleteObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof OrderListHandleEvent) {
//to do something,这里处理
}
}
}
这里 SingletonUtil 就是泛型单例模式。
4、发通知
//通知订单列表
SingletonUtil.getSingleton(OrderListHandleEvent.class).post();
发生变化,发通知,观察者们都能收到。
Android Tips 目录简介
泛型单例模式
观察者模式
Android 应用前后台切换判断
随机数
RecyclerView CheckBox
解决 Activity 退出动画无效问题
arm64-v8a couldn't find "lib_curl.so"
Not Show Tabs In Single Row
TextView 加横线、下划线
新建文件自动 add to VCS
app 的名字老是显示的是库项目的名字
Android Button 字母自动变大写
Activity 做成对话框效果
singleLine is deprecated
fromHtml is deprecated
getColor is deprecated
getDrawable is deprecated
Fragment 懒加载
Android Studio 获取 SHA1
设置默认的签名文件
dimen 代码取值
arrt 代码取值
设置定时
URLEncoder.encode
TextView 做成分割线
屏幕旋转时不销毁
单击返回键两次退出
Android Studio svn commit changelist delete
占位符
Android Studio 头注释和方法注释