【java回调】java两个类之间的回调函数传递
开发中遇到的实际问题:
困难1:两个类只会被系统实例化,无法获取实例对象的地址,所以也就无法实现传统的java回调。
困难2:BroadcastReceiver类会在系统事件消息(android.hardware.action.NEW_PICTURE)产生之后触发onReceive方法,并注销对象之后重新生成自己的实例对象。
尝试1:使用回调 (失败,单纯用回调)
知识:java回调
回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,常用于异步获取处理结果(耗时或处理时间不确定的操作)。
需要定义三个类,分别是主函数类,callback函数的接口类,耗时业务处理类,在业务处理类中,处理完业务之后,执行一个callback函数。
文件:CallBack.java (接口)
package com.sysnotify.lewes.sysnotify_test; /* 创建一个callback接口
* 用于实现java回调,请仔细阅读下面的注释
* */
public interface CallBack {
public void onEndcallback();
}
//用法
/*
//主函数class
public class Main {
public static void main(String[] args) { //入口方法
new TestCallBack().compute(1000, new ComputeCallBackFun() { // 回调函数
public void onComputeEnd() {
System.out.println("end callback!!!"); }
});
}
} //耗时class
public class TestCallBack {
//耗时类中要有一个接受callback的入口函数
public void compute(int n, CallBack callback) {
{ //执行耗时操作
for (int i = 0; i < n; i++) {
System.out.println(i);
}
}
// 执行完调用这个规定格式的callback
callback.onEndcallback();
}
} */
尝试2:使用静态变量+接口回调 (17.1.3成功)
知识:静态变量
静态变量和实例变量的区别在于:
类静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享,静态变量可以通过类名直接访问。静态变量的生命周期取决于类的生命周期,当类被加载的时候,静态变量被创建并分配内存空间,当类被卸载时,静态变量被摧毁,并释放所占有的内存。
类的每一个实例都有相应的实例变量,每创建一个类的实例,java虚拟机为实例变量分配一次内存,实例变量位于堆区中,实例变量的生命周期取决于实例的生命周期,当创建实例时,为实例变量背创建,并分配内存,当实例被销毁时,实例 变量被销毁,并释放所占有的内存空间。
假如成员变量时引用变量,该成员变量结束生命周期时,并不意味着它所引用对象也结束生命周期。变量的生命周期和对象的生命周期是不同的概念。来源: http://leiguomin627-126-com.iteye.com/blog/422214
知识:java调试信息
在调试代码的时候我们需要查看调试信息,那我们就需要用Android Log类。原型Log.v(String tag, String msg)
android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根据首字母对应VERBOSE,DEBUG,INFO, WARN,ERROR。
1、Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");
2、Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.
3、Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
4、Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
5、Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。
关键代码
文件:camerainfo.java (CordovaPlugin入口文件)
这里可以看做class A,由Cordova自动实例化,但无法获取其实例对象地址
package lewes; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONException; //class A
public class camerainfo extends CordovaPlugin{
@Override
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
// 注册监听器-拍照事件
if("init".equals(action)){
new CameraReceiver().setCallback(new CallBack(){
@Override
public void onEndcallback() {
//在运行正确时,返回true,无传值用.success
//callbackContext.success();
// 如果需要返回数值(字符串,对象等),可以用PluginResult;
// 若返回错误要改PluginResult.Status.ERROR
PluginResult mPlugin = new PluginResult(PluginResult.Status.OK,
"photo get!");
mPlugin.setKeepCallback(true);
callbackContext.sendPluginResult(mPlugin);
}
} ); return true;
}
//传递消息到js 方法1 执行回调
callbackContext.error("error");
return false;
}
}
//AndroidManifest.xml 在<application>标签内增加以下内容
<receiver android:enabled="true" android:name="lewes.CameraReceiver">
<intent-filter android:priority="2147483647">
<action android:name="android.hardware.action.NEW_PICTURE" />
<data android:mimeType="image/*" />
</intent-filter>
</receiver>
//camerainfo.java
package lewes; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
//class B
public class CameraReceiver extends BroadcastReceiver {
public static CallBack cb;//关键是在这创建一个静态变量,保存传过来的callback指针
public void setCallback(CallBack callback){
cb=callback;
}
@Override
public void onReceive(Context context, Intent intent) {
cb.onEndcallback();
}
}
文件:CallBack.java (接口)
//文章开头已给出,注释此略
package com.sysnotify.lewes.sysnotify_test;
/* 创建一个callback接口
* */
public interface CallBack {
public void onEndcallback();
}
最终实现思路:java用接口(interface)来实现回调,所以首先定义一个名叫callback的接口,它有一个函数onEndCallback().
在class B 中创建一个接收callback指针的函数 setCallback(CallBack callback),一个储存callback指针的静态变量 public static CallBack cb
在class A 中实现接口的方法onEndCallback() (本文的这里使用了匿名类生成接口 参见http://www.cnblogs.com/yjmyzz/p/3448330.html)
并创建一个class B的实例,用来传递callback指针 new CameraReceiver().setCallback(callback指针)
最终,在class B 的接收事件产生时调用cb.onEndCallback()完成回调。
如果还没看懂,结合代码多看几遍。。。。
【java回调】java两个类之间的回调函数传递的更多相关文章
- python两个类之间变量和函数的调用
1.class_a() class_b() 2.class_b使用class_a中的变量和函数 3.变量class_a中:class_a.num=... 函数class_b中:先实例化class_a( ...
- java string截取两个字符串之间的值
java string截取两个字符串之间的值 import java.util.regex.Matcher; import java.util.regex.Pattern; public class ...
- (转) C++中基类和派生类之间的同名函数的重载问题
下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...
- java中计算两个日期之间天数的程序设计。
//用java编写出一个以下方法计算两个日期之间天数的程序设计. import java.util.regex.Matcher; import java.util.regex.Pattern; pub ...
- Java中的两个类:Desktop和SystemTray
在JDK6中 ,AWT新增加了两个类:Desktop和SystemTray,前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如 ...
- 使用 Attribute +反射 来对两个类之间动态赋值
看同事使用的 一个ORM 框架 中 有这样一个功能 通过特性(附加属性)的功能来 实现的两个类对象之间动态赋值的 功能 觉得这个功能不错,但是同事使用的 ORM 并不是我使用的 Dapper 所 ...
- java输出任意两个日期之间有多少天
package JingDian; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...
- java中静态类与普通类之间区别
所谓静态,指以static关键字修饰的,包括类,方法,块,字段. 非静态,指没有用static 修饰的. 一.静态类的特点 1.全局唯一,任何一次的修改都是全局性的影响 2.只加载一次,优先于非静态 ...
- 两个Select 之间的值的传递
运行效果: 下面是代码: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML ...
随机推荐
- [fiddler] 使用fiddler script自定义代理规则
场景 fiddler作为调试代理工具,可以捕获电脑与互联网之间所有http通讯. 通过可视化操作或命令行可以按某些规则截获特定请求并修改,但当我们需要批量对请求进行更复杂的逻辑操作时,则不是很方便. ...
- Ubuntu 上搭建 Samba 服务器
由于经常要接收同事发送的一些文件,U盘拷来拷去的很麻烦. 在本机Ubuntu上搭了各Samba服务器,过程中遇到点小问题,记录一下 sudo apt-get install samba 创建一个共享目 ...
- cocos2d-x 3.5以后版本的 luasocket
cocos2d-x 3.5后使用luasocket:local SOCKET = require "socket"; 结果运行就报错:[LUA-print] USE " ...
- javascript json字符串与对象相互转换
在实际项目中,经常遇到字符格式的问题,记下来以便日后方便查看.用到两个函数:JSON.stringify() 和 JSON.parse(). 使用ajax向后台请求数据,后台给前端返回数据,明明后端脚 ...
- bzoj4443[SCOI2015]小凸玩矩阵
题意:一个n*m的矩阵(n<=m<=250),要求选出n个数(每行,每列最多选一个),求第k大数的最小值. 首先第k大的意思是从大到小的第k个数(我读错了,WA了一次还以为算法不对...) ...
- centos7下使用yum安装mysql
CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源 wget http://repo.mysql.com/m ...
- WdatePicker小结
WdatePicker.js日期插件: 1. %y 当前年 %M 当前月 %d 当前日 %ld 本月最后一天 %H 当前时 %m 当前分 %s 当前秒 2.可以通过配置minD ...
- Html中列表标签<ul>的使用
借助Html中的列标标签<ul>在某列文字前面添加标注 <html> <head> <title>文字上方添加标记说明</title> &l ...
- UV动画
[猫猫的Unity Shader之旅]之纹理映射 http://blog.csdn.net/dbtxdxy/article/details/46954417 [猫猫的Unity Shader之旅]之U ...
- python 单例模式
单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在 用装饰器方式实现单例模式 #!/usr/bin/python # coding=utf-8 d ...