Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用接口和直接传递活动来实现回调的区别_Android_Android Activity_Callback - Fatal编程技术网

Android 使用接口和直接传递活动来实现回调的区别

Android 使用接口和直接传递活动来实现回调的区别,android,android-activity,callback,Android,Android Activity,Callback,我注意到我可以使用两种方法创建回调: 在实现回调的类的构造函数处接收接口 在实现回调的类的构造函数中接收活动本身 第一种方法 例如,我可以这样做: public MyClass(MyInterface listener) { this.listener = listener; } public MyClass(MyActivity activity) { this.activity = activity; } 我可以通过编写listener.myCallBac

我注意到我可以使用两种方法创建回调:

  • 在实现回调的类的构造函数处接收接口
  • 在实现回调的类的构造函数中接收活动本身
  • 第一种方法 例如,我可以这样做:

        public MyClass(MyInterface listener) {
        this.listener = listener;
    }
    
        public MyClass(MyActivity activity) {
        this.activity = activity;
    }
    
    我可以通过编写
    listener.myCallBackFunction()调用
    MyActivity
    (实现
    MyInterface
    )中定义的
    myCallBackFunction()

    第二种方法 或者我可以这样做:

        public MyClass(MyInterface listener) {
        this.listener = listener;
    }
    
        public MyClass(MyActivity activity) {
        this.activity = activity;
    }
    
    通过编写
    activity.myCallBackFunction()


    我的担忧:一种方法比另一种好吗?如果是,原因是什么?

    在一种方法中,您创建的是接口实例,而在另一种方法中,您创建的是实现活动的实例。最好的是:

    Interface interface;
    
    public myClass(Activity acitivity)
    
    {
       interface = (Interface)activity;
    }
    
    i、 e.向接口进行类型转换活动。现在,您可以在活动中回调重写的函数

    通过这种方式,您现在可以释放活动函数的信息,只需从活动访问接口的重写函数

    如果需要访问接口回调和活动的函数/变量,可以避免类型转换并创建活动对象


    这取决于你的需要

    我认为这取决于您试图实现什么:第一种方法通常更适合,因为
    MyClass
    不需要了解该接口方法的任何实现,因此它非常适合传递不同的对象(例如,使用构造函数中注入的OnItemClickedListener创建的RecyclerView适配器可以在实现接口的不同活动/片段中重复使用,而适配器不需要更改)。这有助于防止耦合


    第二种方法让人疑惑:
    MyClass
    是否与活动生命周期相关?在该活动被系统实际销毁后,它可能仍然保留对该活动的引用,这会泄漏内存,因为活动对象没有被垃圾收集。这是一个设计问题,可以被视为代码气味,不是吗无法在活动本身中实现您想要的,并且依赖于生命周期回调onCreate/../onDestroy?

    通常来说,您最好使用第一种方法。原因如下:

    假设您有4个类,第一个是
    Vehicle
    ,第二个是
    Bicycle
    ,第三个是
    Bus
    ,第三个是
    Subway
    Bus
    Subway
    Vehicle
    的子类。可能有一个方法调用
    drive()
    ,其中应该有一个参数。您认为哪一个参数类型最好?
    自行车
    公共汽车
    地铁
    ,或
    车辆

    显然,通过
    Vehicle
    是最好的,因为您可能希望在将来添加其他类型的车辆,或者您不希望为项目中的不同类型的车辆编写几乎相同的代码。使用接口而不是特定的类是一样的

    因此,将接口传递给方法总是正确的,而且比将特定类型的对象传递给方法要好。您可以始终在其他类中实现接口,它们也将是该方法的参数。您不需要考虑参数的实际类型,这将使您感到困惑,并使您更多地考虑特定类型特定类型的代码。相反,只有一种类型,宏观上只有一段代码


    因此结论是:使用
    MyActivity
    是好的,但是使用
    MyInterface
    更好。

    是一种比另一种更好的方法吗?如果是,为什么?

    使用
    界面
    是最好的方法

    假设你有

    1) 活动
    MyActivity

    2)
    class
    扩展了活动视图异步任务的是
    Myclass

    MyActivity
    Myclass
    都是实现
    MyInterface

    如果要传递活动,则需要再添加一个构造函数

     public MyClass(MyActivity activity) {
        this.activity = activity;
     }
    
     public MyClass(Myclass myclass) {
        this.myclass= myclass;
     }
    
    如果您使用的是接口

    public MyClass(MyInterface listener) {
        this.listener = listener;
    }
    

    就这样

    第一个,正如
    MyInterface
    可以由任何类实现,任何实现iface的类都可以通过它来实现。您假设我正在实现MyInterface。但如果我要通过MyActivity,那么我就不会实现MyInterface,对吗?