众所周知,在android里面充斥着众多的监听器,如一个按钮具有的OnClickListener,能对按钮的点击事件进行监听,这些监听器通常是一个接口,我们可以通过实现接口里的回调方法,执行事件处理。而AsyncTask也能通过其回调方法在恰当的时间执行异步任务(doInBackground()中),并且在执行完毕后回调到onPostExecute(),我们可以在onPostExecute下面获得异步任务的结果,并使结果安全地在UI线程中显示。AsyncTask是个抽象类,这些回调方法可能是抽象方法,也可能是普通的方法,像doInBackground是抽象方法,强制使用AsyncTask的人去实现,而onPostExecute等回调方法则不是抽象的,使用者可选地对其进行重写。

回调方法这种设计在我看来是如此的精妙绝伦,它总能在恰到好处的时间返回和执行正确的事。上面提到了两种实现回调方法的方式:1.是抽象的抽象,面向接口,所有监听器中的方法都必须实现。2.是单纯的抽象,能够可选地进行回调需要的方法。下面我就自己写了两种方式的回调,及说明使用场景。

方式一:使用接口(使用场景:自定义View时作为事件监听器)

/*** 自定义列表头视图* * @author Change* */
public class ListHeadView extends LinearLayout implements OnClickListener {private OnHeadControlListener colLis;private CheckBox c_all;private TextView field1, field2, field3, field4;private Button controlBtn;private final int count = 4;public ListHeadView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);inflateView(context);}public ListHeadView(Context context, AttributeSet attrs) {super(context, attrs);inflateView(context);}public ListHeadView(Context context) {super(context);inflateView(context);}private void initView() {c_all = (CheckBox) this.findViewById(R.id.c_all);field1 = (TextView) findViewById(R.id.field1);field2 = (TextView) findViewById(R.id.field2);field3 = (TextView) findViewById(R.id.field3);field4 = (TextView) findViewById(R.id.field4);controlBtn = (Button) findViewById(R.id.controlBtn);controlBtn.setOnClickListener(this);c_all.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {colLis.onCheckAllChange(isChecked);// 调用1
            }});}private void inflateView(Context context) {View.inflate(context, R.layout.list_head, this);initView();}public void setTexts(String[] texts) {if(texts.length>=count){field1.setText(texts[0]);field2.setText(texts[1]);field3.setText(texts[2]);field4.setText(texts[3]);}else{throw new ArrayIndexOutOfBoundsException("you don't have tomany fields!");}}public void setButtonResource(int resid){controlBtn.setBackgroundResource(resid);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.controlBtn:colLis.onClickRightBtn();// 调用2break;default:break;}}/*** 回调接口,提供按钮和复选框的监听* * @author Change* */public interface OnHeadControlListener {/*** 点击右边按钮后触发*/public void onClickRightBtn();/*** 复选框状态改变后触发* * @param isChecked*/public void onCheckAllChange(boolean isChecked);}/*** 设置监听器* * @param colLis*/public void setOnHeadControlListener(OnHeadControlListener colLis) {this.colLis = colLis;}}

那么,我们在使用的时候就可以通过

setOnHeadControlListener方法去设置监听器了。
ListHeadView headView = new ListHeadView(context);headView.setOnHeadControlListener(new OnHeadControlListener() {@Overridepublic void onClickRightBtn() {Toast.makeText(context, "点击按钮", Toast.LENGTH_SHORT).show();}@Overridepublic void onCheckAllChange(boolean isChecked) {Toast.makeText(context, "选择变化为"+isChecked, Toast.LENGTH_SHORT).show();}});

方式二:使用抽象类(异步任务结果返回)

/*** apk搜索器* * @author Change* */
public abstract class ApkFileSearcher {private String keyword;// 搜索关键字private static final String TAG = ApkFileSearcher.class.getSimpleName();public ApkFileSearcher(String keyword) {this.keyword = keyword;}/*** 从列表中获得关键字匹配的新列表* * @param allApps* @return*/public List<AppsBean> onSearchIn(List<AppsBean> allApps) {List<AppsBean> results = new ArrayList<AppsBean>();for (AppsBean app : allApps) {if (app.appName.contains(keyword)|| app.pkgName.contains(keyword)) {results.add(app);}}allApps.clear();allApps.addAll(results);return allApps;}/*** 抽象方法:回调搜索结果* * @param result*/public abstract void onSearchFinished(List<AppsBean> result);/*** 本地异步搜索* * @param allApps*/public void startAsyncLocalSearch(final List<AppsBean> allApps) {new AsyncTask<Void, Void, List<AppsBean>>() {@Overrideprotected List<AppsBean> doInBackground(Void... params) {return onSearchIn(allApps);}@Overrideprotected void onPostExecute(List<AppsBean> result) {onSearchFinished(result);// 调用,传入结果
            };}.execute();}

使用的时候便要实现其中的抽象方法。

final ApkFileSearcher searcher = new ApkFileSearcher(keyword) {@Overridepublic void onSearchFinished(List<AppsBean> result) {//在界面对结果进行处理。如传入并构建列表适配器
                }};

再次感慨这前人伟大的发明,无敌的回调设计,当然,使用回调方法也有弊端,个人认为大量使用匿名内部类将降低代码的可读性,用的时候需要慎重,不过,贵在用之方便,依旧强调它的特点--恰到好处。

<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

Android视角,精妙绝伦的回调方法相关推荐

  1. android 低内存方法,android onLowMemory低内存回调方法详解

    onLowMemory方法顾名思义就是在app内存低的时候回调,那么怎样才是内存低的标准,回调流程又是如何?我们一起带着问题去看源代码解析. onLowMemory方法在Activity,Servie ...

  2. android view销毁回调,Android View 常用的回调方法

    onFinishInflate() 当View中所有的子控件均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int, ...

  3. android java 回调方法接口

    常用用法:回调方法接口,向上转型动态绑定,常量接口. 回调方法接口: Java代码 public interface ICallback { public void   func(); } publi ...

  4. android自定义照相机改变焦距,Android4.4自定义拍照,回调方法很慢怎么回

    满意答案 huanagain 2018.01.31 采纳率:50%    等级:7 已帮助:1159人 |//自动聚焦 camera.autoFocus(new Camera.AutoFocusCal ...

  5. Android自定义View的实现方法,带你一步步深入了解View(四)

    不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回顾一下,我们一共学习了LayoutInflater的原理分析.视图的绘制流程.视图的状态及重绘等知识,算是把View中很多重要的知识 ...

  6. Android自定义View的实现方法,带你一步步深入了解View

    如果说要按类型来划分的话,自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.那么下面我们就来依次学习一下,每种方式分别是如何自定义View的. 一.自绘控件 自绘控件的意思就 ...

  7. android JNI层线程回调Java函数

    今天,简单讲讲android的jni如何使用jni回调java函数. 之前,我写了部分jni的博客,讲的都是如何从android的java代码调用jni的函数.最近,需要做一个新的功能,在jni的C函 ...

  8. Android中JNI的使用方法

    Android中JNI的使用方法 首先看一下Android平台的框架图: 可以看到Android上层的Application和ApplicationFramework都是使用Java编写, 底层包括系 ...

  9. android startanimation 回调,ScheduledThreadPoolExecutor执行莫名停止问题Android几个动画回调运行线程...

    本文记录两个问题: ScheduleThreadPoolExecutor莫名停止执行.Animation和Animator两个动画回调监听 运行在哪个线程. 一:ScheduleThreadPoolE ...

最新文章

  1. datamodeler mysql_NavicatDataModeler-官方版-数据库设计工具(NavicatDataModeler)1.0.10官方特别版-独木成林...
  2. 移动互联网用户的心理需求【转载】
  3. 无论你在学什么语言,都能有小姐姐来陪着你一起学习!
  4. Spring Boot使用Spring Data Redis操作Redis(单机/集群)
  5. 系统架构设计师考试 重要的部分
  6. 一文教你从零开始设计并实现一个Java扫雷游戏
  7. 鹅厂应届生在600人大群怒怼管理层,反内卷从手撕领导开始......
  8. 从Http的连接到WebSocket
  9. python 操作mysql_Python 操作MySQL
  10. nginx tornado php,tornado+nginx+python 微信公众号接入配置
  11. 火狐浏览器 附件组件 Xpath 使用
  12. 教程:GIMP中改变画布大小
  13. 由入门C语言题目浅析gets()函数的用法
  14. Laravel框架壁纸图库图片上传下载程序源码
  15. mysql一张表有几个主键_一张表可以有多少个主键
  16. Html 5 、Android、iOS 全平台的斗地主游戏全程讲解
  17. python点击网页_python模拟点击网页按钮实现方法
  18. javafx 教程_示例介绍:JavaFX 8打印
  19. win10 更新之后使用win+s 或者 win+Q 出现新闻推荐和热门搜索
  20. Unity UGUI Toggle监听onValueChanged

热门文章

  1. C/C++ 学习笔记:结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法
  2. 【物联网03】 CentOS7编译EMQ源码
  3. iOS 最为经典的壁纸送上!安排
  4. keras提取网络中间层输出、中间层特征
  5. 基于深度学习的语音识别研究-CTC理论推导(四)
  6. Python编程实现——斐波纳契数列
  7. python利用ElementTree读写xml
  8. 看雪技术论坛加密与解密工具新年大礼包2007光盘
  9. windows使用cmd删除目录和文件(详细)
  10. 学习大数据,公司常用开发的编程语言是什么?