我在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
? (例如,迅速
addTarget({ [weak self] self?.myCallback(); })
(如果self为null则停止)