首页 > 解决方案 > Java/Android:将目标处理程序传递给将其作为弱引用引用的自定义按钮的最短方法(lambda?)

问题描述

我在 Android 中创建了我的自定义按钮。之前,我只有一个非常简单的接口来传递目标方法作为按钮的回调:

public interface onTouchInterface {
    void onTouch(); 
}

当我想将回调传递给按钮时,我只使用了 lambda 表达式:

mybutton.addTarget(this::mycallback); 

这是一个快捷方式

mybutton.addTarget(new onTouchInterface() { 
    @Override 
    void onTouch() { this.mycallback() }
});

问题是我意识到this(在我的情况下通常是一个片段)即使在我从任何地方删除我的片段之后仍然在内存中,而垃圾收集器应该已经删除了它。我发现它被我的 lambda 表达式“封装”了。

我的问题是:如何在对此有弱参考的情况下制作最短的语法?目前,我创建了这个类,而不是旧的非常简单的界面:

public abstract static class Target<T>
{
    protected WeakReference<T> scope ;

    static protected class ScopeNotPresentException extends Exception {}

    protected Target(T scope) { this.scope = new WeakReference<T>(scope); }

    // this is the raw callback called by the button when user clicks
    // it throws an exception if the scope is null, otherwise it executes onTouch (to be overrided)
    final public void onTouchRawCallback() throws ScopeNotPresentException {
        if(scope.get() == null)
            throw new ScopeNotPresentException();
        else
            onTouch(scope.get());
    }

    // when this subclassed method is executed, the scope is verified to be not null
    protected void onTouch(T scope) { }

} 

我的按钮类原始回调确实:

try {
    mTarget.onTouchRawCallback();
}
catch(Target.ScopeNotPresentException e){
    Log.w(LOG_TAG, "target button method was ignored because scope weak ref is null");
} 

因此,如果 scope.get() 为 null,则会触发异常并且onTouch()不会调用该异常。最后,我所有的 Fragment 都向它们的按钮添加了一个处理程序,如下所示:

mybutton.addTarget(new MyCustomButton.Target<MyFragment>(this) {
    @Override
    protected void onTouch(MyFragment scope) {
        scope.fragmentCustomClickHandler(); 
    }
});

但这当然比mybutton.addTarget(this::mycallback);. 我看到我不能将 lambda 用于具有传递给构造函数的参数的泛型类型类。

您对更好的实现有任何想法,以便我可以继续使用 lambda 短语法this,同时使用弱引用进行安全检索吗?(例如,在 swift 中, addTarget({ [weak self] self?.myCallback(); })如果 self 为空,它就会停止)

标签: javaandroidlambdaweak-referencesgeneric-type-argument

解决方案


推荐阅读