feat: 深度完善 — 存根转真实实现、UI类方法补全、Java集合/IO增强
存根转真实实现: - ContentResolver: query/insert/update/delete对file://URI真实文件操作, getType用mimetypes - Context: getResources/getAssets/getString/getColor 委托真实Resources - Bitmap.sameAs: PIL像素比对 - Canvas: quickReject/drawTextOnPath/drawPicture/drawDoubleRoundRect 真实实现 - Paint: measureText/breakText/getTextWidths/getFontMetrics/getTextBounds 用PIL字体 - PathMeasure: 真实路径展平/长度计算/坐标切线提取 - Path.op/Region.op: 布尔运算 - Camera: 3D变换矩阵计算 - SystemClock.setCurrentTimeMillis: date -s命令 - Environment.isExternalStorageRemovable: /proc/mounts检查 - Process.myUid: os.getuid() - PowerManager.isPowerSaveMode: CPU governor检查 - Vibrator: Linux LED振动器设备支持 - FileObserver: 轮询线程检测文件变化 - SensorManager.getRotationMatrix: 完整旋转矩阵算法 - BatteryManager: LinuxPower真实电池数据 - Geocoder: Nominatim API逆地理编码 - LocationManager: addProximityAlert/setTestProviderLocation UI类方法补全: - TextView: setPaddingRelative/getTextColor/setBreakStrategy/setJustificationMode - ImageView: setColorFilter/getColorFilter/clearColorFilter - CheckBox/Switch: setOnCheckedChangeListener - ListView: clearChoices - ViewGroup: setLayoutTransition/setTouchscreenBlocksFocus/getChildVisibleRect - MotionEvent: getHistoricalX/Y/Pressure/EventTime/addBatch/getEdgeFlags/setAction Java集合增强: - ArrayList: spliterator/stream - HashSet: spliterator/stream/removeIf - TreeMap: replaceAll/compute/computeIfAbsent/computeIfPresent/merge - LinkedHashMap: clone (保留access_order) - PriorityQueue: spliterator/clone Java IO增强: - BufferedWriter: append/check - PrintWriter: append - ByteArrayOutputStream: writeTo - ByteArrayInputStream: markSupported - BufferedInputStream: available/mark/reset/markSupported + 修复_fill缓冲区填充bug - SequenceInputStream: 补全实现(Enumeration/多流/跨流聚合读取) 修复: - ViewGroup.addView: 合并重复定义为智能参数分派 - view_ext.ViewGroup: 继承view.ViewGroup - view_ext.KeyEvent: 继承view.KeyEvent - hardware_sensor_ext.SensorManager: 继承hardware.SensorManager - app_fragment: 使用java.lang.IllegalStateException - content_intent.Intent: setData/getScheme正确从Uri提取scheme - __init__.py: 补全Fragment/KeyEvent/MotionEvent/TrafficStats/RecyclerView/TreeMap/Vibrator等导出 统计: 221模块, 3662类, 30952方法, 182302行
This commit is contained in:
1 parent
39b1da37c9
commit
4235f8692c
13 files changed
+2248
-163
No files matched your search
@@ -148,6 +148,240 @@ class Enumeration(Stub):
|
||||
return Iterator(self._it)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Stream / Spliterator helpers (lightweight, stdlib-backed)
|
||||
# ============================================================
|
||||
|
||||
class _Spliterator(Stub):
|
||||
"""Lightweight java.util.Spliterator backed by a Python sequence."""
|
||||
ORDERED = 0x00000010
|
||||
DISTINCT = 0x00000001
|
||||
SORTED = 0x00000004
|
||||
SIZED = 0x00000040
|
||||
NONNULL = 0x00000100
|
||||
IMMUTABLE = 0x00000400
|
||||
CONCURRENT = 0x00001000
|
||||
SUBSIZED = 0x00004000
|
||||
|
||||
def __init__(self, data, characteristics: int = 0):
|
||||
super().__init__()
|
||||
self._data = list(data)
|
||||
self._index = 0
|
||||
self._characteristics = (characteristics
|
||||
| _Spliterator.SIZED
|
||||
| _Spliterator.SUBSIZED)
|
||||
|
||||
def tryAdvance(self, action) -> bool:
|
||||
if self._index < len(self._data):
|
||||
action(self._data[self._index])
|
||||
self._index += 1
|
||||
return True
|
||||
return False
|
||||
|
||||
def forEachRemaining(self, action) -> None:
|
||||
while self._index < len(self._data):
|
||||
action(self._data[self._index])
|
||||
self._index += 1
|
||||
|
||||
def trySplit(self):
|
||||
mid = (self._index + len(self._data)) // 2
|
||||
if self._index >= mid:
|
||||
return None
|
||||
split = _Spliterator(self._data[self._index:mid],
|
||||
self._characteristics)
|
||||
self._index = mid
|
||||
return split
|
||||
|
||||
def estimateSize(self) -> int:
|
||||
return len(self._data) - self._index
|
||||
|
||||
def getExactSizeIfKnown(self) -> int:
|
||||
return self.estimateSize()
|
||||
|
||||
def characteristics(self) -> int:
|
||||
return self._characteristics
|
||||
|
||||
def hasCharacteristics(self, characteristics: int) -> bool:
|
||||
return (self._characteristics & characteristics) == characteristics
|
||||
|
||||
def iterator(self) -> Iterator:
|
||||
return Iterator(self._data[self._index:])
|
||||
|
||||
|
||||
class _Stream(Stub):
|
||||
"""Lightweight java.util.stream.Stream wrapper over a Python list."""
|
||||
def __init__(self, data):
|
||||
super().__init__()
|
||||
self._data = list(data)
|
||||
self._parallel = False
|
||||
|
||||
def iterator(self) -> Iterator:
|
||||
return Iterator(self._data)
|
||||
|
||||
def spliterator(self) -> _Spliterator:
|
||||
return _Spliterator(self._data)
|
||||
|
||||
def isParallel(self) -> bool:
|
||||
return self._parallel
|
||||
|
||||
def parallel(self) -> '_Stream':
|
||||
self._parallel = True
|
||||
return self
|
||||
|
||||
def sequential(self) -> '_Stream':
|
||||
self._parallel = False
|
||||
return self
|
||||
|
||||
def unordered(self) -> '_Stream':
|
||||
return self
|
||||
|
||||
def filter(self, predicate) -> '_Stream':
|
||||
return _Stream([x for x in self._data if predicate(x)])
|
||||
|
||||
def map(self, mapper) -> '_Stream':
|
||||
return _Stream([mapper(x) for x in self._data])
|
||||
|
||||
def mapToInt(self, mapper) -> '_Stream':
|
||||
return _Stream([mapper(x) for x in self._data])
|
||||
|
||||
def mapToLong(self, mapper) -> '_Stream':
|
||||
return _Stream([mapper(x) for x in self._data])
|
||||
|
||||
def mapToDouble(self, mapper) -> '_Stream':
|
||||
return _Stream([mapper(x) for x in self._data])
|
||||
|
||||
def flatMap(self, mapper) -> '_Stream':
|
||||
result = []
|
||||
for x in self._data:
|
||||
part = mapper(x)
|
||||
if isinstance(part, (list, tuple)):
|
||||
result.extend(part)
|
||||
else:
|
||||
result.extend(list(part))
|
||||
return _Stream(result)
|
||||
|
||||
def peek(self, action) -> '_Stream':
|
||||
for x in self._data:
|
||||
action(x)
|
||||
return self
|
||||
|
||||
def distinct(self) -> '_Stream':
|
||||
seen = []
|
||||
seen_keys = set()
|
||||
for x in self._data:
|
||||
key = x if isinstance(x, (int, str, tuple, frozenset)) else id(x)
|
||||
if key not in seen_keys:
|
||||
seen_keys.add(key)
|
||||
seen.append(x)
|
||||
return _Stream(seen)
|
||||
|
||||
def sorted(self, key=None, reverse: bool = False) -> '_Stream':
|
||||
return _Stream(sorted(self._data, key=key, reverse=reverse))
|
||||
|
||||
def limit(self, maxSize: int) -> '_Stream':
|
||||
return _Stream(self._data[:maxSize])
|
||||
|
||||
def skip(self, n: int) -> '_Stream':
|
||||
return _Stream(self._data[n:])
|
||||
|
||||
def forEach(self, action) -> None:
|
||||
for x in self._data:
|
||||
action(x)
|
||||
|
||||
def forEachOrdered(self, action) -> None:
|
||||
for x in self._data:
|
||||
action(x)
|
||||
|
||||
def toArray(self, generator=None):
|
||||
if generator is None:
|
||||
return list(self._data)
|
||||
return list(self._data)
|
||||
|
||||
def reduce(self, *args):
|
||||
if len(args) == 1:
|
||||
accumulator = args[0]
|
||||
it = iter(self._data)
|
||||
try:
|
||||
acc = next(it)
|
||||
except StopIteration:
|
||||
return Optional.empty()
|
||||
for x in it:
|
||||
acc = accumulator(acc, x)
|
||||
return Optional.of(acc)
|
||||
elif len(args) == 2:
|
||||
identity, accumulator = args
|
||||
acc = identity
|
||||
for x in self._data:
|
||||
acc = accumulator(acc, x)
|
||||
return acc
|
||||
else:
|
||||
identity, accumulator, combiner = args
|
||||
acc = identity
|
||||
for x in self._data:
|
||||
acc = accumulator(acc, x)
|
||||
return acc
|
||||
|
||||
def collect(self, *args):
|
||||
if not args:
|
||||
return list(self._data)
|
||||
if len(args) == 1:
|
||||
collector = args[0]
|
||||
supplier = getattr(collector, 'supplier', None)
|
||||
accumulator = getattr(collector, 'accumulator', None)
|
||||
finisher = getattr(collector, 'finisher', None)
|
||||
if supplier is not None and accumulator is not None:
|
||||
container = supplier() if callable(supplier) else supplier
|
||||
for x in self._data:
|
||||
if callable(accumulator):
|
||||
accumulator(container, x)
|
||||
if finisher is not None and callable(finisher):
|
||||
return finisher(container)
|
||||
return container
|
||||
if callable(collector):
|
||||
return collector(list(self._data))
|
||||
return list(self._data)
|
||||
supplier, accumulator, combiner = args[0], args[1], args[2]
|
||||
container = supplier() if callable(supplier) else supplier
|
||||
for x in self._data:
|
||||
if callable(accumulator):
|
||||
accumulator(container, x)
|
||||
return container
|
||||
|
||||
def count(self) -> int:
|
||||
return len(self._data)
|
||||
|
||||
def findFirst(self):
|
||||
return Optional.of(self._data[0]) if self._data else Optional.empty()
|
||||
|
||||
def findAny(self):
|
||||
return self.findFirst()
|
||||
|
||||
def anyMatch(self, predicate) -> bool:
|
||||
return any(predicate(x) for x in self._data)
|
||||
|
||||
def allMatch(self, predicate) -> bool:
|
||||
return all(predicate(x) for x in self._data)
|
||||
|
||||
def noneMatch(self, predicate) -> bool:
|
||||
return not any(predicate(x) for x in self._data)
|
||||
|
||||
def min(self, key=None):
|
||||
if not self._data:
|
||||
return Optional.empty()
|
||||
return Optional.of(min(self._data, key=key) if key else min(self._data))
|
||||
|
||||
def max(self, key=None):
|
||||
if not self._data:
|
||||
return Optional.empty()
|
||||
return Optional.of(max(self._data, key=key) if key else max(self._data))
|
||||
|
||||
def onClose(self, close_handler) -> '_Stream':
|
||||
return self
|
||||
|
||||
def close(self) -> None:
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ArrayList
|
||||
# ============================================================
|
||||
@@ -294,6 +528,12 @@ class ArrayList(Stub):
|
||||
def replaceAll(self, operator) -> None:
|
||||
self._data = [operator(x) for x in self._data]
|
||||
|
||||
def spliterator(self) -> _Spliterator:
|
||||
return _Spliterator(self._data, _Spliterator.ORDERED)
|
||||
|
||||
def stream(self) -> _Stream:
|
||||
return _Stream(self._data)
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if isinstance(other, ArrayList):
|
||||
return self._data == other._data
|
||||
@@ -789,6 +1029,10 @@ class LinkedHashMap(HashMap):
|
||||
key = next(iter(self._data))
|
||||
return (key, self._data[key])
|
||||
|
||||
def clone(self) -> 'LinkedHashMap':
|
||||
result = LinkedHashMap(self._data, 0.75, self._access_order)
|
||||
return result
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TreeMap
|
||||
@@ -993,6 +1237,48 @@ class TreeMap(Stub):
|
||||
return True
|
||||
return False
|
||||
|
||||
def replaceAll(self, function) -> None:
|
||||
for k in list(self._data.keys()):
|
||||
self._data[k] = function(k, self._data[k])
|
||||
|
||||
def compute(self, key, remapping_function):
|
||||
old = self._data.get(key)
|
||||
new_val = remapping_function(key, old)
|
||||
if new_val is not None:
|
||||
self._data[key] = new_val
|
||||
return new_val
|
||||
self._data.pop(key, None)
|
||||
return None
|
||||
|
||||
def computeIfAbsent(self, key, mapping_function):
|
||||
if key not in self._data:
|
||||
new_val = mapping_function(key)
|
||||
if new_val is not None:
|
||||
self._data[key] = new_val
|
||||
return new_val
|
||||
return self._data.get(key)
|
||||
|
||||
def computeIfPresent(self, key, remapping_function):
|
||||
if key in self._data:
|
||||
new_val = remapping_function(key, self._data[key])
|
||||
if new_val is not None:
|
||||
self._data[key] = new_val
|
||||
return new_val
|
||||
self._data.pop(key, None)
|
||||
return None
|
||||
|
||||
def merge(self, key, value, remapping_function):
|
||||
old = self._data.get(key)
|
||||
if old is None:
|
||||
self._data[key] = value
|
||||
return value
|
||||
new_val = remapping_function(old, value)
|
||||
if new_val is not None:
|
||||
self._data[key] = new_val
|
||||
return new_val
|
||||
self._data.pop(key, None)
|
||||
return None
|
||||
|
||||
def size(self) -> int:
|
||||
return len(self._data)
|
||||
|
||||
@@ -1140,6 +1426,19 @@ class HashSet(Stub):
|
||||
for item in list(self._data):
|
||||
action(item)
|
||||
|
||||
def removeIf(self, predicate) -> bool:
|
||||
old_size = len(self._data)
|
||||
to_remove = [x for x in self._data if predicate(x)]
|
||||
for x in to_remove:
|
||||
self._data.discard(x)
|
||||
return len(self._data) != old_size
|
||||
|
||||
def spliterator(self) -> _Spliterator:
|
||||
return _Spliterator(self._data, _Spliterator.DISTINCT)
|
||||
|
||||
def stream(self) -> _Stream:
|
||||
return _Stream(self._data)
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if isinstance(other, HashSet):
|
||||
return self._data == other._data
|
||||
@@ -3445,6 +3744,18 @@ class PriorityQueue(Stub):
|
||||
for item in list(self._heap):
|
||||
action(item)
|
||||
|
||||
def spliterator(self) -> _Spliterator:
|
||||
if self._comparator:
|
||||
items = [v[1] for v in self._heap]
|
||||
else:
|
||||
items = list(self._heap)
|
||||
return _Spliterator(items)
|
||||
|
||||
def clone(self) -> 'PriorityQueue':
|
||||
result = PriorityQueue(comparator=self._comparator)
|
||||
result._heap = list(self._heap)
|
||||
return result
|
||||
|
||||
def toString(self) -> str:
|
||||
items = ", ".join(str(x) for x in self._heap)
|
||||
return f"[{items}]"
|
||||
|
||||
Reference in new issue
Block a user