feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
This commit is contained in:
1 parent
506f9ac725
commit
a51854455b
128 files changed
+100571
-3
No files matched your search
@@ -0,0 +1,386 @@
|
||||
"""
|
||||
Java java.lang.ref reference APIs implemented in Python.
|
||||
java.lang.ref package - Reference, ReferenceQueue, SoftReference, WeakReference, PhantomReference, Finalizer.
|
||||
Wraps Python weakref module.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
import weakref as _weakref
|
||||
import threading as _threading
|
||||
import gc as _gc
|
||||
|
||||
__all__ = [
|
||||
"Reference", "SoftReference", "WeakReference", "PhantomReference",
|
||||
"ReferenceQueue", "Finalizer", "FinalizerReference", "FinalizationWatchdog",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ReferenceQueue
|
||||
# ============================================================
|
||||
|
||||
class ReferenceQueue(Stub):
|
||||
"""
|
||||
java.lang.ref.ReferenceQueue
|
||||
A queue that References are appended to when they are enqueued.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._queue: list = []
|
||||
self._lock = _threading.Lock()
|
||||
self._cond = _threading.Condition(self._lock)
|
||||
|
||||
def poll(self):
|
||||
"""
|
||||
Polls to see if a reference object is available.
|
||||
Returns the reference if available, None otherwise.
|
||||
"""
|
||||
with self._lock:
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
|
||||
def remove(self, timeout: int = 0):
|
||||
"""
|
||||
Removes the next reference object from this queue, blocking until one is available
|
||||
or the timeout expires.
|
||||
Args:
|
||||
timeout: timeout in milliseconds (0 = indefinite)
|
||||
Returns:
|
||||
The reference, or None if timeout expired.
|
||||
"""
|
||||
with self._lock:
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
if timeout == 0:
|
||||
self._cond.wait()
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
else:
|
||||
self._cond.wait(timeout / 1000.0)
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
|
||||
def enqueue(self, ref: "Reference") -> bool:
|
||||
"""
|
||||
Enqueues a reference onto this queue.
|
||||
Returns True if successful.
|
||||
"""
|
||||
with self._lock:
|
||||
self._queue.append(ref)
|
||||
self._cond.notify()
|
||||
return True
|
||||
|
||||
def __len__(self):
|
||||
return len(self._queue)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Reference (abstract base)
|
||||
# ============================================================
|
||||
|
||||
class Reference(Stub):
|
||||
"""
|
||||
java.lang.ref.Reference
|
||||
Abstract base class for reference objects.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__()
|
||||
self._referent = referent
|
||||
self._queue = queue
|
||||
self._enqueued = False
|
||||
# Underlying weakref to track referent lifetime
|
||||
self._weak = None
|
||||
if referent is not None:
|
||||
self._weak = _weakref.ref(
|
||||
referent,
|
||||
self._on_referent_collected
|
||||
)
|
||||
|
||||
def _on_referent_collected(self, weakref_obj):
|
||||
"""Called when the referent is garbage collected."""
|
||||
if self._queue is not None and not self._enqueued:
|
||||
self._enqueued = True
|
||||
self._queue.enqueue(self)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Returns this reference object's referent.
|
||||
If the referent has been garbage collected, returns None.
|
||||
"""
|
||||
if self._weak is not None:
|
||||
return self._weak()
|
||||
return self._referent
|
||||
|
||||
def clear(self):
|
||||
"""Clears this reference object."""
|
||||
self._referent = None
|
||||
if self._weak is not None:
|
||||
self._weak = None
|
||||
|
||||
def isEnqueued(self) -> bool:
|
||||
"""Returns whether this reference object has been enqueued."""
|
||||
return self._enqueued
|
||||
|
||||
def enqueue(self) -> bool:
|
||||
"""Enqueues this reference object."""
|
||||
if self._queue is not None and not self._enqueued:
|
||||
self._enqueued = True
|
||||
return self._queue.enqueue(self)
|
||||
return False
|
||||
|
||||
def clone(self):
|
||||
"""Creates a shallow copy of this reference."""
|
||||
return self.__class__(self.get(), self._queue)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"{self.__class__.__name__}@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Reference):
|
||||
return False
|
||||
return self.get() is other.get()
|
||||
|
||||
def hashCode(self) -> int:
|
||||
r = self.get()
|
||||
return hash(r) & 0x7FFFFFFF if r is not None else 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SoftReference
|
||||
# ============================================================
|
||||
|
||||
class SoftReference(Reference):
|
||||
"""
|
||||
java.lang.ref.SoftReference
|
||||
Soft reference objects, cleared at the discretion of the GC.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
self._clock = 0
|
||||
|
||||
def get(self):
|
||||
"""Returns the referent; on desktop, soft references are more resilient."""
|
||||
return super().get()
|
||||
|
||||
def enqueue(self) -> bool:
|
||||
return super().enqueue()
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SoftReference@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# WeakReference
|
||||
# ============================================================
|
||||
|
||||
class WeakReference(Reference):
|
||||
"""
|
||||
java.lang.ref.WeakReference
|
||||
Weak reference objects, cleared automatically by the GC.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"WeakReference@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PhantomReference
|
||||
# ============================================================
|
||||
|
||||
class PhantomReference(Reference):
|
||||
"""
|
||||
java.lang.ref.PhantomReference
|
||||
Phantom reference objects. get() always returns None.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Phantom references always return None.
|
||||
The referent is phantom-reachable and thus not accessible.
|
||||
"""
|
||||
return None
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"PhantomReference@{hex(id(self))}[referent=phantom]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FinalizerReference
|
||||
# ============================================================
|
||||
|
||||
class FinalizerReference(Reference):
|
||||
"""
|
||||
java.lang.ref.FinalizerReference
|
||||
Represents a finalizer reference used by the VM's finalization system.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
self._finalized = False
|
||||
self._finalize_method = None
|
||||
if referent is not None and hasattr(referent, "finalize"):
|
||||
self._finalize_method = getattr(referent, "finalize", None)
|
||||
|
||||
def finalize(self):
|
||||
"""Invokes the referent's finalize method if it exists."""
|
||||
if not self._finalized and self._finalize_method is not None:
|
||||
try:
|
||||
self._finalize_method()
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
self._finalized = True
|
||||
|
||||
def isFinalized(self) -> bool:
|
||||
return self._finalized
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"FinalizerReference@{hex(id(self))}[finalized={self._finalized}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FinalizationWatchdog
|
||||
# ============================================================
|
||||
|
||||
class FinalizationWatchdog(Stub):
|
||||
"""
|
||||
java.lang.ref.FinalizationWatchdog
|
||||
A watchdog thread that ensures finalizations proceed.
|
||||
Desktop stub implementation.
|
||||
"""
|
||||
|
||||
_instance = None
|
||||
_running = False
|
||||
_thread = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._timeout = 10000 # 10 seconds
|
||||
|
||||
@classmethod
|
||||
def getInstance(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = FinalizationWatchdog()
|
||||
return cls._instance
|
||||
|
||||
def start(self):
|
||||
"""Starts the watchdog thread."""
|
||||
if not self._running:
|
||||
self._running = True
|
||||
self._thread = _threading.Thread(target=self._run, daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
"""Stops the watchdog thread."""
|
||||
self._running = False
|
||||
|
||||
def _run(self):
|
||||
"""Watchdog loop."""
|
||||
while self._running:
|
||||
_gc.collect()
|
||||
import time
|
||||
time.sleep(1)
|
||||
|
||||
def setEnabled(self, enabled: bool):
|
||||
if enabled:
|
||||
self.start()
|
||||
else:
|
||||
self.stop()
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"FinalizationWatchdog@{hex(id(self))}[running={self._running}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Finalizer
|
||||
# ============================================================
|
||||
|
||||
class Finalizer(Stub):
|
||||
"""
|
||||
java.lang.ref.Finalizer
|
||||
Manages object finalization. Provides methods to run finalization.
|
||||
"""
|
||||
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@classmethod
|
||||
def runFinalization(cls):
|
||||
"""
|
||||
Runs the finalization methods of any objects pending finalization.
|
||||
Equivalent to calling System.runFinalization().
|
||||
"""
|
||||
_gc.collect()
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def runFinalizersOnExit(cls, value: bool):
|
||||
"""
|
||||
Sets whether finalization is enabled on exit.
|
||||
Deprecated in Java. Desktop stub.
|
||||
"""
|
||||
if value:
|
||||
import atexit
|
||||
atexit.register(cls._finalize_all)
|
||||
|
||||
@classmethod
|
||||
def _finalize_all(cls):
|
||||
"""Finalize all objects on exit."""
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def finalizeAllEnqueued(cls):
|
||||
"""
|
||||
Finalizes all objects that have been enqueued for finalization.
|
||||
"""
|
||||
_gc.collect()
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Finalizer@{hex(id(self))}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
Reference in new issue
Block a user