本身对Java一窍不通,无奈android里Java代码太多,复杂一点的Java代码总会头疼很久。这不,下面的这段代码就晕了。

点击(此处)折叠或打开

  1. DragState mDragState = null;
  2.     574 final InputHandler mDragInputHandler = new BaseInputHandler() {
  3.     575 @Override
  4.     576 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
  5.     577 boolean handled = false;
  6.     578 try {
  7.     579 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
  8.     580 && mDragState != null) {
  9.     581 boolean endDrag = false;
  10.     582 final float newX = event.getRawX();
  11.     583 final float newY = event.getRawY();
  12.     584
  13.     585 switch (event.getAction()) {
  14.     586 case MotionEvent.ACTION_DOWN: {
  15.     587 if (DEBUG_DRAG) {
  16.     588 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
  17.     589 }
  18.     590 } break;
  19.     591
  20.     592 case MotionEvent.ACTION_MOVE: {
  21.     593 synchronized (mWindowMap) {
  22.     594 // move the surface and tell the involved window(s) where we are
  23.     595 mDragState.notifyMoveLw(newX, newY);
  24.     596 }
  25.     597 } break;
  26.     598
  27.     599 case MotionEvent.ACTION_UP: {
  28.     600 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
  29.     601 + newX + "," + newY);
  30.     602 synchronized (mWindowMap) {
  31.     603 endDrag = mDragState.notifyDropLw(newX, newY);
  32.     604 }
  33.     605 } break;
  34.     606
  35.     607 case MotionEvent.ACTION_CANCEL: {
  36.     608 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
  37.     609 endDrag = true;
  38.     610 } break;
  39.     611 }
  40.     612
  41.     613 if (endDrag) {
  42.     614 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
  43.     615 // tell all the windows that the drag has ended
  44.     616 synchronized (mWindowMap) {
  45.     617 mDragState.endDragLw();
  46.     618 }
  47.     619 }
  48.     620
  49.     621 handled = true;
  50.     622 }
  51.     623 } catch (Exception e) {
  52.     624 Slog.e(TAG, "Exception caught by drag handleMotion", e);
  53.     625 } finally {
  54.     626 finishedCallback.finished(handled);
  55.     627 }
  56.     628 }
  57.     629 };

查了一下,这是Java里的匿名类。
=============================================================================

匿名内部类 ( 明白了匿名类就理解了函数回调,(此处与线程无关))有位老兄说:(匿名一是为了简化代码,而是告诉GC我这个对象只用一次,用完给我回收了)

关于JAVA内部类:一个内部类的定义是定义在另一个类内部的类。

  存在它的原因是:

  1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。即内部类实例对包含它的哪个类的实例来说,是特权的。

  2.对于同一个包中的其他类来说,内部类能够隐藏起来,换句话说,内部类不管方法的可见性如何,那怕是public,除了包容类,其他类都无法使用它。

  3.匿名内部类可以很方便的定义回调。

  4.使用内部类可以非常方便的编写事件驱动程序。


其实它真正的目的仅仅为了定义回调--进一步就是事件驱动。

接口和回调:编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。


java的匿名内部类的语法规则看上去有些古怪,不过如同匿名数组一样,当你只需要创建一个类的对象而且用不上它的名字时,使用内部类可以使代码看上去简洁清楚。它的语法规则是这样的: 

new interfacename(){......}; 或 new superclassname(){......}; 

下面接着前面继续举例子: 

public class Goods3 { 
public Contents cont(){ 
return new Contents(){ 
private int i = 11; 
public int value() { 
return i; 

}; 



这里方法cont()使用匿名内部类直接返回了一个实现了接口Contents的类的对象,看上去的确十分简洁。 

在java的事件处理的匿名适配器中,匿名内部类被大量的使用。例如在想关闭窗口时加上这样一句代码: 

frame.addWindowListener(new WindowAdapter(){ 
public void windowClosing(WindowEvent e){ 
System.exit(0); 

}); 

有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法: 

如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final。 
将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。 
在这个匿名内部类中使用初始化代码块。 
为什么需要内部类? 
java内部类有什么好处?为什么需要内部类? 

首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。 

不过你可能要质疑,更改一下方法的不就行了吗? 

的确,以此作为设计内部类的理由,实在没有说服力。 

真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题——没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。


09-28 04:38