Android java回调机制与自定义接口回调方法

Android java回调机制与自定义接口回调方法

摘自:http://baibig.me/2015/04/15/Android-java%E5%9B%9E%E8%B0%83%E6%9C%BA%E5%88%B6%E4%B8%8E%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%9B%9E%E8%B0%83%E6%96%B9%E6%B3%95/

编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写库;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。

当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)。

如下图所示(图片来源:维基百科):


可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。(我认为)这应该是回调最早的应用之处,也是其得名如此的原因。
在Java中,是通过接口和内部类实现回调功能的。android中经常会用到内部类方式的监听接口,如按钮中的onClickListener等,内部类接口中会用到回调方法;同时在多线程操作中,子线程进行耗时操作时,如向服务器发送请求,服务器的数据响应是无法进行的,这时候需要利用java的回调机制解决问题,通过重写回调方法获取请求结果。
这里以网络下载为例,封装一个网络下载类,并且实现自定义接口回调方法。
先建立一个接口:

1
2
3
4
public interface HttpCallBackListener{
    void onFinish(String respose);
    void onError(Exception e);
}

建立封装的网络操作类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class HttpUtil{
    public static void sentHttpRequest(final String address,final HttpCallBackListener listener){
        new Thread(new Runable(){
            public void run(){
                HttpConnection connection=null;
                try{
                    URL url=new URL(address);
                    connection=(HttpConnection)url.openConnection();
                    connection.setRequestMode("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.setDonInput(true);
                    connection.setDoOutput(true);
                    InputStream in=connection.getInputStream();
                    BufferReader br=new BufferReader(new InputStreamReader(in));
                    StringBuilder sb=new StringBuilder();
                    String line;
                    while((line=br.readLine())!=null){
                        sb.append(line);
                }
                if(listener!=null){
                //回调onFinish方法
                    listener.onFinish(response);
            } catch(Exception e){
                if(listenen!=null){
                    listener.onError();

            } final{
                if(connection!=null){
                    connection.disconnect();
                }
            }
        }
            }
        }
        }).start();
}
}

在mainActivity活动中使用工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        
        
        final Handler handler =new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(msg.what==1){
                    String  info =(String) msg.obj;
                    Toast.makeText(getApplicationContext(), ""+info, Toast.LENGTH_SHORT).show();
                }
            }
        };
        
         HttpUtil.sendHttpRequest("http://www.baidu.com",new HttpCallbackListener(){
            
             public void onFinish(String response) {
                 System.out.println(response);
                    Message msg =handler.obtainMessage();
                    msg.what=1;
                    msg.obj=response;
                    handler.sendMessage(msg);
              };
              
              public void onError(Exception e) { 
                  System.out.println("系统出错:"+e.toString());
              };
          });
        
    }

上面代码中通过HttpUtils工具类的sendHttpRequest()方法,传递一个网址参数,通过子线程操作执行数据下载,然后通过重写接口实例,重写接口方法,获取了之前操作的结果;然后将结果通过Handler发送消息,当handler触发handMessage回到方法的时候,就可以获取最终的效果!整个过程用到了接口回调机制和之前常用的监听器效果大同小异,非常有助于理解android的事件回调机制和匿名内部类的使用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值