prevent reference cycles between Java and native objects

This commit is contained in:
Julian Winkler
2024-07-26 21:47:08 +02:00
parent 45801d8f17
commit e3c0931714
30 changed files with 257 additions and 181 deletions

View File

@@ -616,7 +616,7 @@ public class View implements Drawable.Callback {
}
public interface OnLongClickListener {
// TODO
public boolean onLongClick(View v);
}
public interface OnHoverListener {
@@ -964,12 +964,25 @@ public class View implements Drawable.Callback {
this.gravity = gravity;
}
private OnTouchListener on_touch_listener = null;
public boolean onTouchEvent(MotionEvent event) {
return false;
if (on_touch_listener != null)
return on_touch_listener.onTouch(this, event);
else
return false;
}
public native void setOnTouchListener(OnTouchListener l);
public native void setOnClickListener(OnClickListener l);
public void setOnTouchListener(OnTouchListener l) {
nativeSetOnTouchListener(widget);
on_touch_listener = l;
}
protected native void nativeSetOnTouchListener(long widget);
private OnClickListener on_click_listener = null;
public void setOnClickListener(OnClickListener l) {
nativeSetOnClickListener(widget);
on_click_listener = l;
}
protected native void nativeSetOnClickListener(long widget);
public /*native*/ void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {}
public native final int getWidth();
public native final int getHeight();
@@ -1200,7 +1213,18 @@ public class View implements Drawable.Callback {
return null;
}
public native void setOnLongClickListener(OnLongClickListener listener);
private OnLongClickListener on_long_click_listener = null;
public boolean performLongClick(float x, float y) {
if (on_long_click_listener != null) {
return on_long_click_listener.onLongClick(this);
}
return false;
}
public void setOnLongClickListener(OnLongClickListener listener) {
nativeSetOnLongClickListener(widget);
on_long_click_listener = listener;
}
protected native void nativeSetOnLongClickListener(long widget);
public void setLongClickable(boolean longClickable) {}
@@ -1398,6 +1422,7 @@ public class View implements Drawable.Callback {
public boolean isInEditMode() {return false;}
@Override
@SuppressWarnings("deprecation")
protected void finalize() throws Throwable {
try {
native_destructor(widget);
@@ -1504,7 +1529,12 @@ public class View implements Drawable.Callback {
public void setDuplicateParentStateEnabled(boolean enabled) {}
public boolean performClick() {
return false;
if (on_click_listener != null) {
on_click_listener.onClick(this);
return true;
} else {
return false;
}
}
public void playSoundEffect(int soundConstant) {}
@@ -1662,6 +1692,9 @@ public class View implements Drawable.Callback {
protected void onAttachedToWindow () {
attachedToWindow = true;
}
protected void onDetachedFromWindow() {
attachedToWindow = false;
}
public void setLayerType(int layerType, Paint paint) {}

View File

@@ -91,6 +91,8 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
child.parent = null;
children.remove(child);
native_removeView(widget, child.widget);
if (isAttachedToWindow())
child.onDetachedFromWindow();
if (onHierarchyChangeListener != null) {
onHierarchyChangeListener.onChildViewRemoved(this, child);
}
@@ -114,6 +116,8 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
child.parent = null;
it.remove();
native_removeView(widget, child.widget);
if (isAttachedToWindow())
child.onDetachedFromWindow();
if (onHierarchyChangeListener != null) {
onHierarchyChangeListener.onChildViewRemoved(this, child);
}
@@ -317,6 +321,14 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
for (View child: children) {
child.onDetachedFromWindow();
}
}
protected boolean isChildrenDrawingOrderEnabled() { return false; }
@Override

View File

@@ -46,9 +46,16 @@ public class Window {
}
public void setContentView(View view) {
if (contentView != view) {
if (contentView != null)
contentView.onDetachedFromWindow();
if (view != null)
view.onAttachedToWindow();
}
contentView = view;
view.onAttachedToWindow();
set_widget_as_root(native_window, view.widget);
if (view != null) {
set_widget_as_root(native_window, view.widget);
}
}
public View getDecorView() {