轮子哥的Activity"/>
轮子哥的Activity
Activity
BaseActivity
总结
20230714
- 对点击监听的绑定、软键盘的隐藏、向其他activity的跳转、handler事件向主线程的派发、获取intent中具体类型数据这五个常用开发过程做了优化,其中我认为有用的是监听和软键盘的隐藏
- 对startActivityForResult做了很妙的优化:相较于收到数据后业务逻辑在onActivityResult中编写,采用创建接口的方式,在startActivityForResult中就将未来的回调操作业务编写好了,减少了重写onActivityResult的事件,其中RequestCode是采用在0~2^16中随机获取,这个优化非常实用
- 对于有fragment的情况做了点击事件拦截,这一点需要后期开发中具体业务才能知道是否实用
对于接口XxxAction的理解
整体思想
- 封装好一些高效的方法,减少创建类的时间,提高开发效率
- 其中有少许需要子类实现的方法
分别把握
20230714:这里我目前觉得较为常用的是clickAction,keyboardAction次之,毕竟不是所有activity都需要输入框
ClickAction
- 对控件的监听绑定做了优化,可以一次性绑定多个View
ActivityAction
- 简化了跳转此Activity的方法,直接输入要跳转的Activity.class即可(形参是要跳转的目的Activity)。但是需要实现getContext
- 对跳转时的上下文context做了检查,我也不知道在什么情况下context不是Activity
HandlerAction
- 什么是handler?两个作用:处理Msg、发送Msg,在主线程(UI线程)中创建mHandler(这一过程会根据Msg.what编写处理代码),在需要的地方调用mhandler.sendMassage即可去执行Msg.what中的事务但是这个接口不是对发送Msg做优化的
提供了一个全局HANDLER省去new过程,post进行检错优化。关于回调的函数目前还不了解:20230714:回调就是已经放到主线程的消息队列中的runnable- 20230713:handler还有一个作用:发送Rannable(一段可执行的操作,每一个操作都可以设定一个token作为其标识),就是将可执行操作放到主线程的消息队列中去,主线程以此取出消息队列中的消息进行执行。使用情景有:在异步进程中更新UI(实际上,
runOnUiThread()
方法是基于Handler
实现的) - 通过removeCallbacks(runnable)可以取消加入队列的操作
- 因此此接口的作用是:优化了发送runnable的方法,为每一个runnable自动附加了专属token(即:调用此方法的对象,例如A.post®,则r的token就是A)
BundleAction
- Bundle是组件之间传递数据的数据容器
- 优化了各种getXxx方法
- 需要实现getBundle方法(原来Intent中getXxxxExtra都是先获取bundle在通过bundle.getXxxx来获取数据)
- 20230714:我觉得没必要优化直接调用intent.getStringExtra即可
KeyboardAction
- 对软键盘的一些配置,还搞不懂
- 20230710:hideKeyboard(View view) 隐藏view所在的窗口中的软键盘
与常规配置Activity有何差异
-
onCreated中仅存在总的init函数,其中包括对布局的初始化(其中封装了setContextView),控件的初始化以及数据的初始化。对这三类初始化分别定义了三个抽象方法:getLayoutId()、initView()、initData()
-
在初始化布局中,对软键盘进行了初始化:点击非键盘区域时,软键盘会隐藏。这里调用了KeyboardAction接口中的方法
-
对activity来回切换时回调(onActivityResult)做了优化,通过创建回调函数,使得原本在onActivityResult中写的方法转移到了startActivityForResult中编写,提高了效率
startActivityForResult & onActivityResult
常规步骤
-
在调用方编写
-
跳转要Result的Activity时,使用StartActivityForResult(intent,requestCode),其中intent就是正常的跳转intent,requestCode是为了辨别是哪一个StartActivityForResult发起的跳转,比如一个Activity中同时存在跳向B\C的两个StartActivityForResult,后续onActivityResult中需要辨别B\C的回调时就可以用RequestCode识别
-
编写onActivity(requestcode,resultcode,intent):requestcode就不多说了,resultcode是Result的activity的一个回复状态码,就类似网页中404这种,用来对返回的数据做一个状态判断,这个resultcode是用户自己在Result的activity中编写。intent是Result的activity返回的带数据的一个“容器”
-
在被调用方编写
-
若要返回数据,则创建一个intent对象,空的就行,不需要和常规跳转时intent一样。然后put数据即可
-
使用setResult(resultcode,intent)发送,当无需返回数据时,参数只写resultcode即可。注意:此方法实现跳转业务,需要通过finish()来结束result的activity,不可使用startActivity,因为startActivity不会调用onActivityResult(补充一点:当activity为singleXxxx时,若此activity被startActivity跳转时,此activity回调用onNewIntent方法)
优化思路
- 业务中只需要提供三个参数:去哪(activity.class),携带什么(bundle),收到数据干点什么(callback):因此创造带这三个参数的startActivityForResult
- requestCode怎么办:它的作用是区分多调用者(上面在“常规步骤第二步”已经解释)。因此它本质上来说不是业务层该考虑的事情,分辨的工作由内部来处理。因此需要做一个表,类似键值对,requestCode—interface,所以用SparseArray来进行存储。requestCode通过随机获得
- 在此函数中,完成requestCode的随机获取、键值对的put,之后调用原生函数startActivityForResult
- 在onActivityResult中取出对应requestCode的callback接口后调用其callback即可,调用结束后清除此接口。若不存在requestCode对应的接口则调用super.nActivityResult
对软键盘的一些操作
这里只总结一些我目前需要的功能
点击非键盘区时,键盘消失
总思想: 在非键盘区域(根视图)设置监听,只要点击就隐藏键盘;如果根视图被其他视图盖住的区域此监听不生效
-
获取非键盘区域的控件:我的理解是软键盘是将整个activity向上挤,因此只需要获取activity这个最大控件即可。轮子哥在这使用了findViewById(Window.ID_ANDROID_CONTENT)来获取ViewGroup(ViewGroup继承View)
-
隐藏键盘:调用了关于键盘的接口(KeyboardAction)中hideKeyboard(view)。其中view为被键盘挤上去的控件群(因为整个布局都被键盘挤上去了)。此方法具体执行流程:
-
从控件所处的上下文中获取键盘的管理类InputMethodManager
InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-
监听中传入的参数不是view而是getCurrentFocus的原因:常规来说,点击事件触发时,焦点会立即转到被点击的控件,此时view就是getCurrentFocus,但是当某个控件设置了focusable=false则焦点并不会转移:view!=getCurrentFocus。另外在点击时通过编程手段使得其他控件立即获得焦点时,焦点会发生转移此时view!=getCurrentFocus,具体的业务中还未发现上述情况带来的bug,选择getCurrentFocus得到的控件范围不只是view,这样提高容错率,因此选择getCurrentFocus
-
利用token找到view所在窗口,将此窗口中的键盘隐藏。(token时每一个窗口的标识符,就好比身份证号)
manager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
-
当整个窗口(我觉得是activity的根控件)布满控件时,点击其中控件并不会触发上述监听
-
我现在认为上面一点的解决方案就是,在离开某个activity或fragment时隐藏键盘。或者在使用键盘时,暂时黑掉其他无关输入的控件群(类似弹出输入对话框时,其他地方调暗,只用输入对话框高亮)
-
当activity finish时、startActivityForResult(也可以在onPause中)做键盘隐藏工作,以免内存泄漏
我不理解为什么隐藏键盘要在finish而不是onDestory,finish会调用onDestory,直接在onDestory中处理不就好了
更新intent
当activity设为singleXxxx时,若此activity在栈顶部,则调用onNewIntent方法,其中参数intent是新的intent而非原来activity中的intent,此时需要使用setIntent来更新此activity中的intent。onNewIntent()的作用就是对旧Activity重启时,对新intent的操作
监听拦截
对baseFragment事件的拦截
如果有BaseFragment需要处理某个点击事件,此优化将会在activity响应此事件时进行拦截,转由此fragment处理
更多推荐
轮子哥的Activity
发布评论