技术类探讨--单个Handler解决一个应用刷新通知问题
来源:互联网 发布:c语言中合法的标识符 编辑:程序博客网 时间:2024/06/03 18:36
熟知Android的童鞋一定对Handler不陌生,Android的Handler可以进行UI Thread和普通Thread之间的数据交互操作。笔者喜欢用一个Handler解决一个Application之间的线程通信问题。这样做的方式,可以降低每个Activity和Fragment之间Handler的创建数量。尽可能的优化代码。
笔者从嵌入式转行做Android也有些时日了,参考了某国内股票公司的一些设计思想,配置+复用的思想沿用至今。对于一个Application尽可能的考虑少写代码多做功能。程序好比是搭积木,一个一个小的模块,组合成不同的应用。具体采用了观察+注册的思想模式,每个业务都在系统注册一个唯一的标识作为业务代码模块的核心,然后通过系统调用的方式,调度到某一个、某一级别的业务层代码。
如下所示的代码基础类方式,比如Activity为例:
public abstract class BasicActivity<M, V> extends AppCompatActivity implements LDNetDateCallback { private Handler mHandler = new Handler(Loop.getMainLoop()); private LDDataSetObserver mServer; protected V mView; protected M mModel; protected int mIds; //业务系统ID private View headerView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
//封装通用组件,比如title,底部导航栏,等等通用组件工具,用动态加载的方式实现。 } public View getHeaderView() { return headerView; } private void registSystem() { registActivity(); } protected void onCreateActivity(Bundle savedInstanceState) { } private void registActivity() { IntentFilter filter = new IntentFilter(); filter.addAction(MSG_LOGOUT); filter.addAction(MSG_NETWORK_ERROR); filter.addAction(MSG_SERVICE_START); filter.addAction(MSG_SERVICE_STOP); registerReceiver(this.mBroadcastReceiver, filter); // 注册 } /** * 方法描述: * <p/> * 参数: * 返回: * 创建人:Genesis * 创建时间:16/5/19 * 修改备注: * * @version */ public void setLeftBtnVisable(int isVisable) { } public V getControllerView() { return mView; } public void setControllerView(V mView) { if (mServer != null) { mServer.setView(mView); } this.mView = mView; } public M getModel() { return mModel; } public void setModel(M mModel) { if (mServer != null) { mServer.setModel(mModel); } this.mModel = mModel; } /** * 方法描述: * 设置右边按键的可见性 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ public void setRightBtnVisable(int isVisable) { if (mTitleBar != null) { mTitleBar.setRightVisable(isVisable == View.VISIBLE); } } /** * 方法描述: * 显示等待框Dialog * <p> * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ protected void showWait(String msg) { } @Override protected void onResume() { super.onResume(); } /** * 方法描述: * 取得titlebar相关控件的引用 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ public TitleBar getTitleBar() { return mTitleBar; } /** * 隐藏dialog框 */ protected void hideWait() { } /** * 方法描述: * 设置title * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ protected void setTitle(String title) { mTitleBar = (TitleBar) findViewById(R.id.title_bar); if (mTitleBar != null) { mTitleBar.setTitle(title); mTitleBar.invalidate(); } } /** * 方法描述: * 设置做标题监听事件 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ public void setTopLeftBtnListener(View.OnClickListener onClickListener) { setLeftBtnVisable(View.VISIBLE); if (mTitleBar != null) { mTitleBar.setLeftClickListener(onClickListener); } } /** * 方法描述: * 设置右标题 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ public void addRightBtnAction(TitleBar.Action action) { setRightBtnVisable(View.VISIBLE); if (mTitleBar != null) { mTitleBar.addAction(action); } } public int getIds() { return mIds; } public void setIds(int mIds) { this.mIds = mIds; } /** * 方法描述: * 清楚所有Action * 参数: * 返回: * 创建人:Genesis * 创建时间:16/9/13 * 修改备注: * * @version */ public void clearRightBtnAction() { if (mTitleBar != null) { mTitleBar.removeAllActions(); mTitleBar.invalidate(); } } @Override protected void onDestroy() { super.onDestroy(); BasicApplication.getSysApplication().notifyDataInvalidated(); BasicApplication.getSysApplication().unregisterDataSetObserver(mServer); } public boolean hasLollipop() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } protected int getObserverId() { if (mServer == null) { return mIds; } return mServer.getIds(); } protected abstract void initView(); protected abstract int onCreateViewResID();}总体的设计思想,一个ID对应一个业务模块,每个Activity中有一个注册机制,在系统Application中注册相应的ID,然后当系统侦测到对应的数据,会做相应的函数调度。主要采用MVC的设计方式,Mode负责数据业务解析,View做视图渲染方面。提供一些基本的函数入口,比如:
public abstract class BasicLayout<T> extends LinearLayout { public BasicLayout(Context context) { super(context); } public BasicLayout(Context context, AttributeSet attrs) { super(context, attrs); } public BasicLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 方法描述: * 框架自动处理Model数据 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/10/22 * 修改备注: * * @version */ public abstract void onFreshModel(T model);}
比如在View中,实现一个onFreshModel接口,实现model的插入,所要的数据都对该model数据进行翻译。model中可以提供相应的方法。用于数据解析,不过笔者在这里的操作是通过Handler调用。
if (mModel != null) { if (mModel instanceof BasicModel) { new Thread(new Runnable() { @Override public void run() { ((BasicModel) mModel).parseParam(param); mController.onChanged(mModel); Message message = new Message(); message.what = Constant.MSG_VIEW_REFRESH; LDDataSetObject object = new LDDataSetObject(mModel, mView); message.obj = object; mHandler.sendMessage(message); } }).start(); } } mController.onChanged(param);}在回调地方新建一个线程处理业务代码,可以是二进制流也可以是其它的对象,然后用model进行数据处理。最后发送到系统主要单利全局Handler中进行数据刷新。
/** * 方法描述: * 系统调度刷新业务接口 * 参数: * 返回: * 创建人:Genesis * 创建时间:16/10/21 * 修改备注: * * @version */protected static Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == Constant.MSG_VIEW_REFRESH) { if (msg.obj instanceof LDDataSetObject) { LDDataSetObject object = (LDDataSetObject) msg.obj; final Object model = object.getModel(); final Object view = object.getView(); if (view != null) { if (view instanceof BasicLayout) { mHandler.post(new Runnable() { @Override public void run() { ((BasicLayout) view).onFreshModel((BasicModel) model); } }); } } } } }};接收到消息后,再自动显示到对应的视图渲染器中,进行图层渲染。其实本质上讲,就是M V中提供一个接口方法,然后通过这个接口方法,进行数据刷新、数据处理,保证系统少用一些Handler,方便代码编写,代码就好比是一个模块孔槽,在对应的地方写入相关的业务,然后刷新、数据获取什么的都不必考虑。当然有些地方需要使用Handler的delay方式,可以在此基础上复用。新增一些消息即可。
其实做法还有很多种,这里只是提供了一种方式,
0 0
- 技术类探讨--单个Handler解决一个应用刷新通知问题
- 页面实时刷新技术探讨
- 页面实时刷新技术探讨
- 页面实时刷新技术探讨
- 解决一个重大技术问题
- dom刷新问题再探讨
- Web页面实时刷新技术探讨
- Web页面实时刷新技术探讨
- Web页面实时刷新技术探讨
- Web页面实时刷新技术探讨
- Web页面实时刷新技术探讨
- Web页面实时刷新技术探讨
- 手机银行技术应用探讨
- 手机银行技术应用探讨
- MPLS技术的应用探讨
- 解决handler警告问题
- 解决angular单个页面只能加载一个ng-app的问题
- 解决CListCtrl刷新问题
- 第一次使用studio设置以及常用插件
- 欢迎使用CSDN-markdown编辑器
- tensorflow debug
- 二分贪心练习--T(用最少的箱子放所有的货物)
- c++ 链接mysql:error LNK2019: 无法解析的外部符号
- 技术类探讨--单个Handler解决一个应用刷新通知问题
- 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件时失败解决方法
- Lombok的安装、使用说明
- react-naitve我踩得第一个坑
- [EmguCV|C#]使用CvInvoke自己繪製色彩直方圖-直方圖(Hitsogram)系列(4)
- python3.6对MySQL数据恢复
- Leetcode-Graph-Hash
- HTML精华记录(一)
- mysql模糊查询like通配符使用介绍