[关闭]
@weidong 2017-07-09T02:45:00.000000Z 字数 6993 阅读 355

接口回调

未分类


摘抄

http://www.jianshu.com/p/c3da97948cd0
http://www.jianshu.com/p/345e36572e66
http://www.mobile-open.com/2016/980232.html

接口回调是指

解释一:

可以把使用实现了某一接口的类创建的对象的引用,赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。

解释二:

接口回调就是指: 可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。简单来说就是A(主线程)很忙没工夫去做一些无聊的——>这时候来了个B(子线程),B说:老大你这么忙,技术活你来 CV这种活就我来吧! 这时候A和B就开始疯狂输出了.但是A又想知道B到底搞定了没有.咋办? 这时候电话C(接口类)来了,当B做完了体力活就拿起电话C开始跟A发了个短信告诉A我搞定了 .然后A就知道B搞定了 开始疯狂输出下一个技术活.好了,话不多说开始撸代码.

解释三

理解一个东西,必须从它的本源入手,再实例化到生活事例中,加深理解,毕竟程序是对现实生活的一种抽象。
而android中的回调,遵循的基本思想是Java中的回调函数。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

Java 中没有指针的概念,通过接口和内部类的方式实现回调的功能:
1. 定义接口 Callback ,包含回调方法 callback()
2. 在一个类Caller 中声明一个Callback接口对象 mCallback
3. 在程序中赋予 Caller对象的接口成员(mCallback) 一个内部类对象如
new Callback(){
callback(){
//函数的具体实现
}
这样,在需要的时候,可用Caller对象的mCallback接口成员 调用callback()方法,完成回调.

---我---是---华---丽---的---分---割---线---

其实接口回调根本就是:对象方法的调用

以下例子为巩固代码
上例子1:
简单对象方法调用

  1. public class MainActivity extends AppCompatActivity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. CallBackDemo callBackDemo = new CallBackDemo();
  7. callBackDemo.show();
  8. }
  9. class CallBackDemo{
  10. public void show(){
  11. Toast.makeText(MainActivity.this, "哈哈哈", Toast.LENGTH_SHORT).show();
  12. }
  13. }
  14. }

例子2:
让别人调用我们方法,类分开了

  1. public class MainActivity extends AppCompatActivity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. ShowLog callBackDemo = new ShowLog();
  7. //让别人调我们的方法
  8. CallBackUtils.testCallBack(callBackDemo);
  9. }
  10. }
  11. public class CallBackUtils {
  12. public static void testCallBack(ShowLog showToast) {
  13. showToast.show();
  14. }
  15. }
  16. class ShowLog {
  17. private static final String TAG = "ShowLog";
  18. public void show() {
  19. Log.e(TAG, "show: 显示日志信息啦");
  20. }
  21. }

例子3:
可以重写方法

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. ShowLog callBackDemo = new ShowLog(){
  8. @Override
  9. public void show() {
  10. Log.e(TAG, "show: 重写方法,实现自己独有的打印");
  11. }
  12. };
  13. //让别人调我们的方法
  14. CallBackUtils.testCallBack(callBackDemo);
  15. }
  16. }
  17. public class CallBackUtils {
  18. public static void testCallBack(ShowLog showToast) {
  19. showToast.show();
  20. }
  21. }
  22. class ShowLog {
  23. private static final String TAG = "ShowLog";
  24. public void show() {
  25. Log.e(TAG, "show: 显示日志信息啦");
  26. }
  27. }

例子4:
如果确定每个人都有自己特有的输出方式,那么可以使用接口来编写ShowLog类,代码就变成

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. //基于接口的特性,此时创建ShowLog对象就必须实现show()方法了
  8. ShowLog callBackDemo = new ShowLog(){
  9. @Override
  10. public void show() {
  11. Log.e(TAG, "show: 重写方法,实现自己独有的打印");
  12. }
  13. };
  14. //让别人调我们的方法
  15. CallBackUtils.testCallBack(callBackDemo);
  16. }
  17. }
  18. public interface ShowLog {
  19. public void show();
  20. }
  21. public class CallBackUtils {
  22. public static void testCallBack(ShowLog showToast) {
  23. showToast.show();
  24. }
  25. }

线

亲,例子4用到了接口回到,你感受到了吗?

不就是将普通类换成接口而已吗?
不就是利用了接口的特性,必须实现接口的方法而已吗?

来来来,我们模拟一个多人开发环境,学学接口回调的使用场景

公司有两个员工 A(美女)、B(屌丝男)

项目代码不多时,A和B各自写了一个方法,B的方法执行完(相当于网络请求完)就会调用A的方法,A就可以乐呵乐呵写界面啦

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. try {
  8. request();
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. //A 编写的方法
  14. public void request() throws InterruptedException {
  15. //模拟网络请求啦
  16. Thread.sleep(1000);
  17. //请求到数据展示啦
  18. onNetSucceed("我是结果");
  19. }
  20. //B 编写的方法,这里显示请求结果数据
  21. public void onNetSucceed(String result){
  22. }
  23. }

随着需求的变动,项目的需求越来越多,需要在请求网络数据(调用methodsB()方法之前)给出提示,机智的B怎么可能会错过装逼的会呢,想了一天一夜,就对代码做了如下修改

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. try {
  8. onNetStart();
  9. request();
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. //我是网络请求之前调用,可以显示弹出框等。
  15. public void onNetStart(){
  16. }
  17. //A 编写的方法
  18. public void request() throws InterruptedException {
  19. //模拟网络请求啦
  20. Thread.sleep(1000);
  21. //请求到数据展示啦
  22. onNetSucceed("我是结果");
  23. }
  24. //B 编写的方法,这里显示请求结果数据
  25. public void onNetSucceed(String result){
  26. }
  27. }

又随着需求的变动,发现网络不好的情况下,应用就没有办法提示错误的信息了,本来B想趁此机会和A好好讨论一番,但是A红着脸说,上次不就是你改的吗?然后没有然后了,B又想了一夜

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. try {
  8. onNetStart();
  9. request();
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. //我是网络请求之前调用,可以显示弹出框等。
  15. public void onNetStart(){
  16. }
  17. //A 编写的方法
  18. public void request() throws InterruptedException {
  19. //模拟网络请求啦
  20. Thread.sleep(1000);
  21. boolean isError = true;//模拟错误和正确
  22. if(isError){
  23. onNetSucceed("我是结果");
  24. }else{
  25. onNetFailure("我错误啦");
  26. }
  27. }
  28. //B 编写的方法,这里显示正确数据
  29. public void onNetSucceed(String result){
  30. }
  31. //B 编写的方法,这里显示网络请求错误
  32. public void onNetFailure(String result){
  33. }
  34. }

还是随着需求的变动,MainActivity里面的代码越来越点多,导致开发越来越困难,B想出了一个方法,将代码分成两个类,网络请求的代码放到名为HttpUtils的类中,B还是想借此机会好好和A讨论加班一番,最重要的是可以和A独处,为此还特意去买了份狗肉火锅,想和A边加班边吃,得知有狗肉吃的A很是开心,眼冒金星问B:"我可能要吃两人份,可不可以啦啦啦啦啦啦啦啦啦,巴拉巴拉巴拉"

B:行!(能够和你独处,你吃了我都行)

A和她男朋友绣着恩爱,吃着狗肉,看着饿着的单身狗加班一个晚上。

虽然B收到了几吨伤害,当是代码还是要写的

因为HttpUtils类的methodsB_1() 需要调用MainActivity的methodsA_1()、methodsA_3()方法,所以将MainActivity对象传给methodsB_1()方法

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. try {
  8. HttpUtils httpUtils = new HttpUtils();
  9. httpUtils.request(this);
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. //我是网络请求之前调用,可以显示弹出框等。
  15. public void onNetStart(){
  16. }
  17. //B 编写的方法,这里显示正确数据
  18. public void onNetSucceed(String result){
  19. }
  20. //B 编写的方法,这里显示网络请求错误
  21. public void onNetFailure(String result){
  22. }
  23. }
  24. public class HttpUtils {
  25. //A 编写的方法
  26. public void request(MainActivity mainActivity) throws InterruptedException {
  27. onNetStart();
  28. //模拟网络请求啦
  29. Thread.sleep(1000);
  30. boolean isError = true;//模拟错误和正确
  31. if(isError){
  32. mainActivity.onNetSucceed("我是结果");
  33. }else{
  34. mainActivity.onNetFailure("我错误啦");
  35. }
  36. }
  37. }

当是这样完美了吗?

使用回调写法

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String TAG = "MainActivity";
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. HttpUtils httpUtils = new HttpUtils();
  8. httpUtils.request(new HttpUtils.NetCallback() {
  9. @Override
  10. public void onNetStart() {
  11. }
  12. @Override
  13. public void onNetSucceed() {
  14. }
  15. @Override
  16. public void onNetFailure() {
  17. }
  18. });
  19. }
  20. }
  21. public class HttpUtils {
  22. //A 编写的方法
  23. public void request(NetCallback netCallback) {
  24. netCallback.onNetStart();
  25. //模拟网络请求啦
  26. try {
  27. Thread.sleep(1000);
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. }
  31. boolean isError = true;//模拟错误和正确
  32. if (isError) {
  33. netCallback.onNetSucceed();
  34. } else {
  35. netCallback.onNetFailure();
  36. }
  37. }
  38. //网络请求状态的回调
  39. interface NetCallback {
  40. void onNetStart();//请求开始
  41. void onNetSucceed();//请求成功
  42. void onNetFailure();//请求失败
  43. }
  44. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注