今天给大家分享一下个人对接口回调的理解...
1.先来解释一下什么叫做接口回调
接口回调就是指: 可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。简单来说就是A(主线程)很忙没工夫去做一些无聊的——>这时候来了个B(子线程),B说:老大你这么忙,技术活你来 CV这种活就我来吧! 这时候A和B就开始疯狂输出了.但是A又想知道B到底搞定了没有.咋办? 这时候电话C(接口类)来了,当B做完了体力活就拿起电话C开始跟A发了个短信告诉A我搞定了 .然后A就知道B搞定了 开始疯狂输出下一个技术活.好了,话不多说开始撸代码.
2.这是真实项目Splash界面中提醒用户是否要更新版本的代码
但是我要写一个下载的油条 让代码更具有复用性 就要开始使用接口回调机制让每次下载的时候都能执行installApk(file)的方法.
2.1我是万能的A线程
- 该方法用来下载文件
protected void showUpdateDialog(final UpdateInfo info) {
// 弹出对话窗
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// 积极和消极的按钮设置点击事件.
builder.setTitle("更新提醒");
builder.setMessage(info.getDesc());
builder.setPositiveButton("宝宝乖,点我吧.",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// 开始下载
String url = info.getUrl();
File file = new File(Environment.getExternalStorageDirectory(),
url.substring(url.lastIndexOf("/") + 1));
// 这时候就需要一个接口OnDownloadListener()传输进来
Utils.download(url, file, new OnDownloadListener() {
public void onSuccess(File file) {
// 成功的时候调用
installApk(file);
}
public void onFailed() {
// 失败的时候调用 TODO
}
});
}
});
builder.setNegativeButton("哎呀我酱油啦",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// 点击dialog的时候调用 TODO
}
});
builder.create().show();
}
2.2我是苦逼的B线程(工具类 具有复用性)
-
该方法用来下载文件
@param path 下载文件的网络路径
@param file 下载的文件放在哪个文件中
@param listener 通过接口来实现消息机制 即约定成功的时候做什么 失败的时候做什么.
//protected static final int SUCCESS = 0; // 定义常量SUCCESS用于筛选成功事件
//protected static final int FAILED = 1; // 定义常量FAILED用于筛选失败事件public static void download(final String path, final File file, final OnDownloadListener listener){final Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: if (listener != null) { listener.onSuccess(file); } break; case FAILED: if (listener != null) { listener.onFailed(); } break; } } }; // 这里是联网操作 大部分框架都是基于url下载. // 所以这里用初级代码进行演示.当然也可以用比较流行的okHttp这样的联网框架. new Thread(new Runnable() { public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.setConnectTimeout(3000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); FileOutputStream fos = new FileOutputStream(file); int len = -1; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { fos.write(buffer, 0, len); } fos.close(); handler.sendEmptyMessage(SUCCESS); } } catch (Exception e) { handler.sendEmptyMessage(FAILED); } } }).start();
2.3 我是用来打电话的C接口(接口类 成功调用onsucess; 失败调用onfailed)
public interface OnDownloadListener {
void onSuccess(File file);
void onFailed();
}
3总结一下自己的心得
1.其实我们一开始初学的时候 不会想到接口回调机制,而只会讲对象中的上下文当作对象传递然后强转对象,利用对象调用类中特有的方法.发现复用性几乎为0,因为你每次传递一个数据的时候都要修改油条中的获取对象代码.2.后来我们会想用类去实现,定义一个抽象类,将用匿名内部类重写类中的抽象方法的对象传递过去.这样也能完美的解决问题,但是我们会有一个很大的弊端,这也是谷歌为什么会有接口来弥补父类的不足,因为一个类只能继承一个类(单继承),当你一个已经继承的类再想去继承的时候就会出现冲突.3.这时候就需要一个接口(多实现)去写抽象类方法.这样就是接口回调的机制的形成.就是传入一个对象,例如:
private OnDownloadListener listener;
private setOnDownloadListener(OnDownloadListener listener){
this.listener = listener;
}
//在子线程中工作实现后调用方法,然后再主线程中调用设置监听事件
listener.onSuccess(); listentner.onFailed();
这个对象是匿名内部类并重写的了自己的方法,传过去之后可以调用内部类中的方法例如:
setOnDownloadListener(new OnDownloadListener(){
//这里就是你new出来的的匿名内部类对象
@Override
public void onSuccess() {
//成功的时候做什么
}
@Override
public void onFailed() {
//失败的时候做什么
}
})