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:
shuiyu1123 committed 2026-06-25 00:17:50 +00:00
1 parent 39b1da37c9
commit 4235f8692c
13 files changed
+2248 -163

No files matched your search

+168 -25
View File
@@ -745,14 +745,48 @@ class BufferedInputStream(FilterInputStream):
return total if total > 0 else -1
def _fill(self):
data = self._in.read(bytearray(self._buf_size), 0, self._buf_size)
if data is None or data == -1:
tmp = bytearray(self._buf_size)
n = self._in.read(tmp, 0, self._buf_size)
if n is None or n == -1:
return False
n = data if isinstance(data, int) else len(data)
self._buffer = bytearray(self._in._buffer if hasattr(self._in, '_buffer') else data) if n > 0 else bytearray()
if isinstance(n, (bytes, bytearray)):
# defensive: underlying stream returned raw data instead of a count
tmp = bytearray(n)
n = len(tmp)
if not isinstance(n, int) or n <= 0:
return False
self._buffer = bytearray(tmp[:n])
self._pos = 0
self._count = n
return n > 0
return True
def available(self):
buf_avail = self._count - self._pos
if buf_avail < 0:
buf_avail = 0
try:
underlying = self._in.available()
if underlying and underlying > 0:
return buf_avail + underlying
except Exception:
pass
return buf_avail
def mark(self, readlimit):
self._mark_pos = self._pos
self._mark_buffer = bytes(self._buffer)
self._mark_count = self._count
self._mark_limit = readlimit
def reset(self):
if not hasattr(self, '_mark_pos'):
raise IOException("Resetting to invalid mark")
self._buffer = bytearray(self._mark_buffer)
self._count = self._mark_count
self._pos = self._mark_pos
def markSupported(self):
return True
# ============================================================
@@ -1034,6 +1068,26 @@ class BufferedWriter(Closeable, Flushable):
def newLine(self):
self._buffer.append("\n")
def append(self, csq=None, start=None, end=None):
if csq is None:
return self
if isinstance(csq, int):
self._buffer.append(chr(csq))
else:
s = str(csq)
if start is not None and end is not None:
s = s[start:end]
elif start is not None:
s = s[start:]
self._buffer.append(s)
if sum(len(x) for x in self._buffer) >= self._buf_size:
self.flush()
return self
def check(self):
if getattr(self._writer, '_closed', False):
raise IOException("Stream closed")
def flush(self):
if self._buffer:
data = "".join(self._buffer)
@@ -1171,6 +1225,20 @@ class PrintWriter(Closeable, Flushable):
else:
self._write_str(str(s))
def append(self, csq=None, start=None, end=None):
if csq is None:
csq = "null"
if isinstance(csq, int):
self._write_str(chr(csq))
else:
s = str(csq)
if start is not None and end is not None:
s = s[start:end]
elif start is not None:
s = s[start:]
self._write_str(s)
return self
def format(self, fmt, *args):
s = str(fmt) % args if args else str(fmt)
self._write_str(s)
@@ -1256,6 +1324,9 @@ class ByteArrayInputStream(Closeable):
def reset(self):
self._pos = self._mark
def markSupported(self):
return True
# ============================================================
# ByteArrayOutputStream
@@ -1283,6 +1354,11 @@ class ByteArrayOutputStream(Closeable, Flushable):
def toByteArray(self):
return bytes(self._buf)
def writeTo(self, out):
if self._closed:
raise IOException("Stream closed")
out.write(bytes(self._buf))
def size(self):
return len(self._buf)
@@ -1730,37 +1806,104 @@ class PushbackInputStream(FilterInputStream):
# SequenceInputStream
# ============================================================
def _is_enumeration(obj) -> bool:
"""True if obj really exposes hasMoreElements/nextElement (not via Stub)."""
for cls in type(obj).__mro__:
if ('hasMoreElements' in cls.__dict__
and 'nextElement' in cls.__dict__):
return True
return False
class SequenceInputStream(Closeable):
def __init__(self, streams):
def __init__(self, *args):
super().__init__()
if hasattr(streams, 'hasMoreElements'):
self._streams = []
while streams.hasMoreElements():
self._streams.append(streams.nextElement())
else:
self._streams = list(streams)
self._streams = []
self._current_idx = 0
self._closed = False
if len(args) == 0:
return
if len(args) == 1:
streams = args[0]
if isinstance(streams, (list, tuple)):
self._streams = list(streams)
elif _is_enumeration(streams):
while streams.hasMoreElements():
self._streams.append(streams.nextElement())
else:
# single stream
self._streams = [streams]
else:
# SequenceInputStream(s1, s2, ...)
self._streams = list(args)
def _current(self):
if self._current_idx < len(self._streams):
return self._streams[self._current_idx]
while self._current_idx < len(self._streams):
inp = self._streams[self._current_idx]
if inp is None:
self._current_idx += 1
continue
return inp
return None
def read(self, b=None, off=None, length=None):
while self._current():
inp = self._current()
if b is None:
result = inp.read()
else:
result = inp.read(b, off, length)
if result != -1:
return result
def _advance(self):
if self._current_idx < len(self._streams):
cur = self._streams[self._current_idx]
if cur is not None:
try:
cur.close()
except Exception:
pass
self._current_idx += 1
return -1
def read(self, b=None, off=None, length=None):
if self._closed:
raise IOException("Stream closed")
if b is None:
while True:
inp = self._current()
if inp is None:
return -1
result = inp.read()
if result != -1:
return result
self._advance()
if off is None:
off = 0
if length is None:
length = len(b)
total = 0
while total < length:
inp = self._current()
if inp is None:
break
n = inp.read(b, off + total, length - total)
if n is None or n == -1:
self._advance()
continue
if n == 0:
self._advance()
continue
total += n
return total if total > 0 else -1
def available(self):
inp = self._current()
if inp is None:
return 0
try:
return inp.available()
except Exception:
return 0
def close(self):
self._closed = True
for s in self._streams:
s.close()
if s is not None:
try:
s.close()
except Exception:
pass
# ============================================================