设计Android的设计模式-观察者模式

观察者模式->定义对象间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖它的对象都得到通知并被自动更新

何时使用:当一个对象的数据更新时,需要通知其他对象,而又不希望和被通知的对象形成紧耦合时;

优点:对象之间解耦;程序中包含一个被观察者、多个观察者,观察者之前又互不相关

适用场景:
1.获取短信验证码,

/**
 * 创建抽象观察者
 **/
public interface Observer {
	// 定义一个接到通知的方法
	void update(int time);
	
	// 完成
	void finish();
}
/**
 * 创建抽象被观察者
 **/
public interface Observable {
	// 添加观察者
	void add(Observer observer);
	
	// 开启定时器
	void startTimer(int count);
}
/**
 * 创建具体被观察者
 **/
public class TimberObservable implements Observable {
	private Observer mObserver;
	@Override
    public void add(Observer observer) {
    	this.mObserver = observer;
  	}
  	
	@Override
    public void startTimer(int count) {
    	try {
			for (int i=count; i>0; i--) {
    			if (mObserver != null) {
    				if (i == 0) {
    					mObserver.finish();
    				} else {
    					mObserver.update(i);
    				}
    			}
    			Thread.sleep(1 * 1000);
    		}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
  	}
}
/**
 * 点击获取验证码
 **/
private Observable observable;
private Button btnGetCode;
private void startTimer() {
	if (observable != null) {
		return;
	}
	btnGetCode.setEnable(false);
	observable = new TimberObservable();
	observable.add(new Observer {
		@Override
		void update(int time) {
			String text = time + "秒后重发";
			btnGetCode.setText(text);
		}
		
		@Override
		void finish() {
			btnGetCode.setText("重新获取");
			btnGetCode.setEnable(true);
			observable = null;
		}
	});
	observable.startTimer(60);
}

用RxJava2实现如下:

// 获取验证码线程
private DisposableSubscriber<Long> mGetCodeThread = null       
private void startTimer() {
	if (mGetCodeThread != null && !mGetCodeThread.isDisposed) {
	    Log.e("TAG", "getCodeThread has init ")
        return
    }
    btnGetCode.setEnable(false);
    mGetCodeThread = new DisposableSubscriber<Long>() {
    	override 
    	void onNext(Long aLong) {
       		String text = (60 - aLong) + "秒后重发";
			btnGetCode.setText(text);
	   	}

        override 
        void onError(Throwable t) {
        	btnGetCode.setEnable(true);
        	btnGetCode.setText("获取验证码"); 
       	}   

       	override 
       	void onComplete() {
	   	    btnGetCode.setEnable(true);
    		btnGetCode.setText("获取验证码");
    		if (!mGetCodeThread.isDisposed) {
                mGetCodeThread.dispose();
            }
       	}
    };
  	// 间隔1秒执行一次
	Flowable.interval(1, TimeUnit.SECONDS).take(60)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(mGetCodeThread);
}

2.监听网络变化

/**
 * 网络状态枚举
 **/
public enum NetWorkState {
    WIFI,   // Wi-Fi网络
    GPRS,   // 移动蜂窝网络
    NONE    // 没有网络
}
/**
 * 创建抽象观察者
 **/
public interface INetObserver {
	// 定义一个接到通知的方法
	void notify(NetWorkState state);
}
/**
 * 创建具体被观察者
 **/
public class NetMonitorManager {
	private Context mContext;
    // 存储接受网络状态变化消息的方法的map
    private Map<Object, INetObserver> mNetMap = new HashMap<>();

    private NetMonitorManager() {

    }

	// 初始化
    public void init(Context context) {
        if (context == null) {
            throw new NullPointerException("context can not be null");
        }
        this.mContext = context;
        initMonitor();
    }

	public void onDestroy() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        	if (mContext != null) {
            	mContext.unregisterReceiver(receiver);
            }
        }
    }

	// 初始化网络监听 根据不同版本做不同的处理
    private void initMonitor() {
        ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //API 大于26时
            if (cm != null) {
            	cm.registerDefaultNetworkCallback(networkCallback);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //API 大于21时
            NetworkRequest.Builder builder = new NetworkRequest.Builder();
            NetworkRequest request = builder.build();
            if (cm != null) {
            	cm.registerNetworkCallback(request, networkCallback);
            }
        } else {
            //低版本
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ANDROID_NET_CHANGE_ACTION);
            mContext.registerReceiver(receiver, intentFilter);
        }
    }

	/**
     * api >= 21
     * */
    @SuppressLint("NewApi")
    ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
        // 网络可用的回调连接成功
        @Override
        public void onAvailable(Network network) {
            super.onAvailable(network);
            int netType = getAPNType();
            NetWorkState netWorkState;
            switch (netType) {
                case 0:     // None
                    netWorkState = NetWorkState.NONE;
                    break;
                case 1:     // Wifi
                    netWorkState = NetWorkState.WIFI;
                    break;
                default:    // GPRS
                    netWorkState = NetWorkState.GPRS;
                    break;
            }
            postNetState(netWorkState);
        }

        // 网络不可用时调用和onAvailable成对出现
        @Override
        public void onLost(Network network) {
            super.onLost(network);
            postNetState(NetWorkState.NONE);
        }

        // 在网络连接正常的情况下,丢失数据会有回调 即将断开时
        @Override
        public void onLosing(Network network, int maxMsToLive) {
            super.onLosing(network, maxMsToLive);
        }

        // 网络功能更改 满足需求时调用
        @Override
        public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
            super.onCapabilitiesChanged(network, networkCapabilities);
        }

        // 网络连接属性修改时调用
        @Override
        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
            super.onLinkPropertiesChanged(network, linkProperties);
        }

        // 网络缺失network时调用
        @Override
        public void onUnavailable() {
            super.onUnavailable();
        }
    };  

	// api < 21
    private static final String ANDROID_NET_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)) {
                // 网络发生变化 没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2
                int netType = getAPNType();
                NetWorkState netWorkState;
                switch (netType) {
                    case 0://None
                        netWorkState = NetWorkState.NONE;
                        break;
                    case 1://Wifi
                        netWorkState = NetWorkState.WIFI;
                        break;
                    default://GPRS
                        netWorkState = NetWorkState.GPRS;
                        break;
                }
                postNetState(netWorkState);
            }
        }
    };

	// 获取当前的网络状态:没有网络-0;WIFI网络-1;4G网络-4;3G网络-3;2G网络-2
    private static int getAPNType() {
        //结果返回值
        int netType = 0;
        //获取手机所有连接管理对象
        ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        //获取NetworkInfo对象
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        //NetworkInfo对象为空 则代表没有网络
        if (networkInfo == null) {
            return netType;
        }
        //否则 NetworkInfo对象不为空 则获取该networkInfo的类型
        int nType = networkInfo.getType();
        if (nType == ConnectivityManager.TYPE_WIFI) {
            //WIFI
            netType = 1;
        } else if (nType == ConnectivityManager.TYPE_MOBILE) {
            int nSubType = networkInfo.getSubtype();
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService
                    (Context.TELEPHONY_SERVICE);
            //3G   联通的3G为UMTS或HSDPA 电信的3G为EVDO
            if (nSubType == TelephonyManager.NETWORK_TYPE_LTE
                    && !telephonyManager.isNetworkRoaming()) {
                netType = 4;
            } else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS
                    || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA
                    || nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0
                    && !telephonyManager.isNetworkRoaming()) {
                netType = 3;
                //2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA
            } else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS
                    || nSubType == TelephonyManager.NETWORK_TYPE_EDGE
                    || nSubType == TelephonyManager.NETWORK_TYPE_CDMA
                    && !telephonyManager.isNetworkRoaming()) {
                netType = 2;
            } else {
                netType = 2;
            }
        }
        return netType;
    }  	

	 // 网络状态发生变化,需要去通知更改
    private void postNetState(NetWorkState state) {
        Set<Object> set = mNetMap.keySet();
        for (Object object : set) {
            INetObserver observer = mNetMap.get(object);
            if (observer != null) {
            	observer.notify(state);
            }
        }
    }
	
	// 注册观察者
	public void register(Object object, INetObserver observer) {
		if (object != null && observer != null) {
            mNetMap.put(object, observer);
        }
	}
	
	// 取消观察者
	public void unregister(Object object) {
		if (object != null) {
            mNetMap.remove(object);
        }
	}
    
	// 静态内部类实现单例
  	private static final class NetWorkHolder {
        private static final NetMonitorManager instance = new NetMonitorManager();
    }

    public static NetMonitorManager getInstance() {
        return NetWorkHolder.instance;
    }
}
/**
 * 实现初始化
 **/
public class MainActivity extends AppCompatActivity {
	@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        NetMonitorManager.getInstance().init(this);
    }
}
 
/**
 * 实现网络监听
 **/
public class AActivity extends AppCompatActivity implements INetObserver {
	@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        NetMonitorManager.getInstance().register(AActivity.this, this);
    }
  
  	public void notify(NetWorkState state) {
  		// 网络变化后处理对应的事件
  	}

	@Override
    protected void onDestroy() {
        super.onDestroy();
        NetMonitorManager.getInstance().unregister(AActivity.this);
	}
}
/**
 * 实现网络监听
 **/
public class BActivity extends AppCompatActivity implements INetObserver {
	@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        NetMonitorManager.getInstance().register(BActivity.this, this);
    }
  
  	public void notify(NetWorkState state) {
  		// 网络变化后处理对应的事件
  	}

	@Override
    protected void onDestroy() {
        super.onDestroy();
        NetMonitorManager.getInstance().unregister(BActivity.this);
	}
}

其他场景,后续再补上

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值