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
+168
-25
@@ -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
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
Reference in new issue
Block a user