在android中引入信号与槽的机制主要是进行消息的传递,比如:
通过对象A产生了一个消息,现在想将这个消息传递到对象B,并由对象B对这个消息进行相应的处理。

先写下信号与槽机制的实现:

            
  1. package mythware.libj; 
  2.  
  3. import java.lang.reflect.InvocationTargetException; 
  4. import java.lang.reflect.Method; 
  5. import java.util.ArrayList; 
  6.  
  7. /* 
  8.  *  by Yanhui Shen under new BSD license, 2011 
  9.  *  Email: [email protected] 
  10.  *   
  11.  *  NOTE:  
  12.  *  1. The Signal/Slot should be public member. 
  13.  *  2. Be careful with Signal-Signal (without loop please). 
  14.  *  3. Enjoy it! 
  15.  * 
  16.  */ 
  17.  
  18. //采用信号槽机制 
  19. public final class SignalSlot { 
  20.      
  21.     //slot用来进行管理相应的响应函数 
  22.     public final static class Slot { 
  23.          
  24.         private final Object mReceiver;      
  25.         private final String mFnName; 
  26.         private final Class<?>[] mArgts; 
  27.         private final Method mFn; 
  28.          
  29.         /** 
  30.          * @param recver 
  31.          *            method receiver 
  32.          * @param fnName 
  33.          *            method name, the method should be public 
  34.          * @param argts 
  35.          *            the arguments' data type 
  36.          * @author shen 
  37.          */ 
  38.         //初始化slot 
  39.         public Slot(Object recver, String fnName, Class<?>[] argts) { 
  40.             mReceiver = recver; 
  41.             mFnName = fnName; 
  42.             mArgts = argts; 
  43.             mFn = tryGetMethod(recver, fnName, argts);           
  44.         } 
  45.          
  46.         /** 
  47.          * Call this to execute the method 
  48.          *  
  49.          * @author shen 
  50.          */ 
  51.         //进行信号的响应,即调用相应的函数 
  52.         public void exec(Object... args) { 
  53.             try { 
  54.                 mFn.invoke(mReceiver, args); 
  55.             } catch (IllegalArgumentException e) { 
  56.                 e.printStackTrace(); 
  57.                 execDiagnosis(args); 
  58.             } catch (IllegalAccessException e) { 
  59.                 e.printStackTrace(); 
  60.                 execDiagnosis(args); 
  61.             } catch (InvocationTargetException e) { 
  62.                 e.printStackTrace(); 
  63.                 execDiagnosis(args); 
  64.             } 
  65.         } 
  66.  
  67.         //获得响应的类 
  68.         public Object getRecviver() { 
  69.             return mReceiver; 
  70.         } 
  71.  
  72.         //获得响应的函数的名字 
  73.         public String getMethodName() { 
  74.             return mFnName; 
  75.         } 
  76.  
  77.         //获得响应的函数 
  78.         private static Method tryGetMethod(Object recver, String fnName, Class<?>[] argts) { 
  79.             Method fn = null
  80.             try { 
  81.                 fn = recver.getClass().getMethod(fnName, argts); 
  82.                 fn.setAccessible(true); 
  83.             } catch (SecurityException e) { 
  84.                 e.printStackTrace(); 
  85.             } catch (NoSuchMethodException e) { 
  86.                 e.printStackTrace(); 
  87.             } 
  88.             return fn; 
  89.         } 
  90.          
  91.         //对函数调用失败的诊断 
  92.         private void execDiagnosis(Object... args) { 
  93.             String msg = mArgts.length == 0 ? "void" : ""
  94.             for (Class<?> argt : mArgts) { 
  95.                 msg += argt.getName() + ", "
  96.             } 
  97.             System.out.println("expected args:" + msg); 
  98.  
  99.             msg = args.length == 0 ? "void" : ""
  100.             for (Object arg : args) { 
  101.                 msg += arg.getClass().getName() + ", "
  102.             } 
  103.             System.out.println("received args:" + msg); 
  104.  
  105.             System.out.println("fn:" + mFn.toString()); 
  106.         }    
  107.     } 
  108.  
  109.     //信号signal用来连接signal和slot的关系 
  110.     public final static class Signal { 
  111.         private final Class<?>[] mArgts; 
  112.         private final ArrayList mSlots = new ArrayList(); 
  113.         private final ArrayList mSignals = new ArrayList(); 
  114.          
  115.         /** 
  116.          * @param argts 
  117.          *            the arguments' data type 
  118.          * @author shen 
  119.          */ 
  120.         //添加相应的参数的类型 
  121.         public Signal(Class<?>... argts) { 
  122.             mArgts = new Class[argts.length]; 
  123.             int index = 0
  124.             for (Class<?> argt: argts) { 
  125.                 mArgts[index++] = argt; 
  126.             } 
  127.         } 
  128.  
  129.         //发出信号,同时让slot进行响应 
  130.         public void emit(Object... args) { 
  131.             for (int i = 0, loopCount = mSignals.size(); i < loopCount; ++i) { 
  132.                 mSignals.get(i).emit(args); 
  133.             } 
  134.  
  135.             for (int i = 0, loopCount = mSlots.size(); i < loopCount; ++i) { 
  136.                 mSlots.get(i).exec(args); 
  137.             } 
  138.         } 
  139.  
  140.         /** 
  141.          * connect to slot 
  142.          *  
  143.          * @author shen 
  144.          */ 
  145.          
  146.         //将信号与槽进行绑定 
  147.         public void connect(Slot slot) { 
  148.             mSlots.add(slot); 
  149.         } 
  150.  
  151.         /** 
  152.          * Provide the receiver and method name, 
     
  153.          * then auto build the slot, meanwhile connect to signal 
  154.          *  
  155.          * @author shen 
  156.          */ 
  157.         //将信号与相关的类即函数名进行绑定 
  158.         public Slot connect(Object recv, String fn) { 
  159.             Slot slot = new Slot(recv, fn, mArgts); 
  160.             mSlots.add(slot); 
  161.             return slot; 
  162.         } 
  163.  
  164.         /** 
  165.          * Disconnect with the slot 
  166.          *  
  167.          * @author shen 
  168.          */ 
  169.         public void disconnect(Slot slot) { 
  170.             mSlots.remove(slot); 
  171.         } 
  172.  
  173.         /** 
  174.          * Disconnect with slots by the specified receiver,
     
  175.          * this can be helpful when you want to disconnect all signals with an 
  176.          * object 
  177.          *  
  178.          * @author shen 
  179.          */ 
  180.         public void disconnectReceiver(Object obj) { 
  181.             for (int i = 0, loopCount = mSlots.size(); i < loopCount; ++i) { 
  182.                 Slot slot = mSlots.get(i); 
  183.                 if (slot.getRecviver().equals(obj)) { 
  184.                     mSlots.remove(slot); 
  185.                     break
  186.                 } 
  187.             } 
  188.         } 
  189.  
  190.         /** 
  191.          * Disconnect with all slots and signals 
  192.          *  
  193.          * @author shen 
  194.          */ 
  195.         public void disconnectAll() { 
  196.             mSlots.clear(); 
  197.             mSignals.clear(); 
  198.         } 
  199.     } 

接下来解释如何来使用:

            
  1. public class A { 
  2.     public Signal sigTest = new Signal(Boolean.class); 
  3.      
  4.     public A(){ 
  5.         sigTest.emit(true); 
  6.     } 
  7.  
  8. class B { 
  9.     public A mAobject = new A(); 
  10.  
  11.     public B() { 
  12.         mAobject.sigTest.connect(this"RespondFunction"); 
  13.     } 
  14.      
  15.     public void RespondFunction(Boolean flag){ 
  16.         System.out.println("Responded!"); 
  17.     } 

如此便结束了。总结一下,其实也挺简单的。

更多相关文章

  1. 使用Kotlin开发Android 扩展函数(Extensions)
  2. android调用高版本api函数的兼容性问题
  3. Android O system函数执行reboot命令失败
  4. Android下使用dlopen函数动态调用.so链接库 [转]
  5. Intent传递对象的两种方法(Serializable,Parcelable)
  6. Android系列之Intent传递对象的两种方法
  7. Android studio插件GsonFormat,返回json快速创建实体对象

随机推荐

  1. 我的erlang TCP服务器
  2. AM:纳米PbTiO3中铁电增强
  3. C语言中用于计算数组长度的函数 “strlen
  4. Wiley人物专访—马里兰大学莫一非教授
  5. 把一个"结构体"当做属性后碰到的问题
  6. AFM:具有优异储钾性能的氮/磷共掺杂空心多
  7. Rust、Erlang 并发数量比较
  8. 原创 | matplotlib绘图教程,设置标签与图
  9. 上周送书结果公布
  10. 解决Play框架启动提示JVM内存分配失败的