feat: 第三轮深度完善 — SQLite/JSON/网络/媒体/文本 真实实现
SQLite真实数据库: - SQLiteDatabase: execSQL/insert/insertOrThrow/replace/update/delete/query 用sqlite3 - 修复getVersion/setVersion用PRAGMA user_version - 修复getMaximumSize/getPageSize/setMaximumSize/setPageSize用PRAGMA - SQLiteStatement: execute/simpleQueryForLong/simpleQueryForString/execQuery - SQLiteOpenHelper: onCreate/onUpgrade/onDowngrade回调正确触发 - 修复SQLiteCursor.moveToPosition越界处理 - 修复ContentValues值对提取bug JSON真实实现: - JSONObject: isNull/append/putOnce/putOpt/getNames - JSONArray: 完整put/get/opt/length/toString 网络真实实现: - NetworkInterface: getByName/getNetworkInterfaces/getHardwareAddress 用/sys/class/net+fcntl.ioctl - InterfaceAddress: 新增类 - ConnectivityManager: getActiveNetwork/getAllNetworks 用LinuxNetwork - WifiManager: getScanResults用nmcli, setWifiEnabled用nmcli/rfkill - BluetoothAdapter: getAddress/getName 用bluetoothctl 媒体真实实现: - MediaPlayer: prepare检查文件, getCurrentPosition实时计算, getDuration/getVideoWidth用ffprobe - MediaRecorder: setVideoSize/setVideoFrameRate/setVideoEncodingBitRate配置存储 - MediaMetadataRetriever: extractMetadata用ffprobe, getFrameAtTime用ffmpeg, getEmbeddedPicture用ffmpeg 文本真实实现: - TextUtils: split用re.split, concat/indexOf/lastIndexOf/urlEncode/urlDecode - SpannableString: setSpan/getSpans/getSpanFlags/nextSpanTransition 真实实现 - SpannableStringBuilder: 修复append重载bug Provider增强: - Settings: putBoolean/getBoolean - MediaStore: getContentUri/VOLUME常量 - ContactsContract: 补全常量和CommonDataKinds Util增强: - Log: w/e/wtf支持Throwable参数, 修复wtf重复定义bug - TypedValue: 修复complexToDimension/complexToFloat/getFloat实现 修复: - __init__.py: 补全NetworkInterface/InetAddress/MediaMetadataRetriever/SpannableStringBuilder导出 统计: 221模块, 3666类, 31005方法, 183529行
This commit is contained in:
1 parent
4235f8692c
commit
fbb8263b13
13 files changed
+1373
-146
No files matched your search
@@ -5,6 +5,7 @@ Android Util 组件 — Log, SparseArray, LruCache, DisplayMetrics 等
|
||||
|
||||
import math
|
||||
import re as _re
|
||||
import struct
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Any, Callable, Dict, Generic, List, Optional, Set, Tuple, TypeVar, Union
|
||||
@@ -51,19 +52,44 @@ class Log(Stub):
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def w(tag: str, msg: str) -> int:
|
||||
def w(tag: str, msg: str = None, tr: Exception = None) -> int:
|
||||
if Log._min_log_level <= Log.WARN:
|
||||
# 支持 w(tag, Throwable) 调用形式
|
||||
if msg is None and tr is not None:
|
||||
msg = Log.getStackTraceString(tr)
|
||||
elif tr is not None:
|
||||
msg = f"{msg}\n{Log.getStackTraceString(tr)}"
|
||||
sys.stderr.write(f"W/{tag}: {msg}\n")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def e(tag: str, msg: str) -> int:
|
||||
def e(tag: str, msg: str = None, tr: Exception = None) -> int:
|
||||
if Log._min_log_level <= Log.ERROR:
|
||||
# 支持 e(tag, Throwable) 调用形式
|
||||
if msg is None and tr is not None:
|
||||
msg = Log.getStackTraceString(tr)
|
||||
elif tr is not None:
|
||||
msg = f"{msg}\n{Log.getStackTraceString(tr)}"
|
||||
sys.stderr.write(f"E/{tag}: {msg}\n")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def wtf(tag: str, msg: str) -> int:
|
||||
def wtf(tag: str, msg=None, tr: Exception = None) -> int:
|
||||
"""What a Terrible Failure。支持以下调用形式:
|
||||
- wtf(tag, msg)
|
||||
- wtf(tag, Throwable)
|
||||
- wtf(tag, msg, Throwable)
|
||||
"""
|
||||
# 如果 msg 是异常对象,则当作 tr 处理
|
||||
if isinstance(msg, BaseException):
|
||||
tr = msg
|
||||
msg = None
|
||||
if msg is None and tr is not None:
|
||||
msg = Log.getStackTraceString(tr)
|
||||
elif tr is not None:
|
||||
msg = f"{msg}\n{Log.getStackTraceString(tr)}"
|
||||
if msg is None:
|
||||
msg = ""
|
||||
sys.stderr.write(f"WTF/{tag}: {msg}\n")
|
||||
return 0
|
||||
|
||||
@@ -88,17 +114,16 @@ class Log(Stub):
|
||||
@staticmethod
|
||||
def getStackTraceString(tr: Exception) -> str:
|
||||
import traceback
|
||||
if tr is None:
|
||||
return ""
|
||||
if isinstance(tr, str):
|
||||
return tr
|
||||
return "".join(traceback.format_exception(type(tr), tr, tr.__traceback__))
|
||||
|
||||
@staticmethod
|
||||
def setMinLogLevel(level: int):
|
||||
Log._min_log_level = level
|
||||
|
||||
@staticmethod
|
||||
def wtf(tag: str, tr: Exception) -> int:
|
||||
sys.stderr.write(f"WTF/{tag}: {Log.getStackTraceString(tr)}\n")
|
||||
return 0
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# SparseArray
|
||||
@@ -518,6 +543,23 @@ class TypedValue(Stub):
|
||||
COMPLEX_UNIT_FRACTION = 6
|
||||
COMPLEX_UNIT_FRACTION_PARENT = 7
|
||||
|
||||
COMPLEX_UNIT_SHIFT = 0
|
||||
COMPLEX_UNIT_MASK = 0xF
|
||||
|
||||
COMPLEX_RADIX_SHIFT = 4
|
||||
COMPLEX_RADIX_MASK = 0x3
|
||||
|
||||
COMPLEX_MANTISSA_SHIFT = 8
|
||||
COMPLEX_MANTISSA_MASK = 0x00ffffff
|
||||
|
||||
# 复数值的基数乘数(与 AOSP TypedValue.RADIX_MULTS 一致)
|
||||
_RADIX_MULTS = (
|
||||
0.00390625, # 1/256, radix 0
|
||||
3.0517578e-5, # 1/32768, radix 1
|
||||
1.1920929e-7, # 1/8388608, radix 2
|
||||
4.6566129e-10, # 1/2147483648, radix 3
|
||||
)
|
||||
|
||||
TYPE_NULL = 0x00
|
||||
TYPE_REFERENCE = 0x01
|
||||
TYPE_ATTRIBUTE = 0x02
|
||||
@@ -536,6 +578,9 @@ class TypedValue(Stub):
|
||||
TYPE_LAST_COLOR_INT = 0x1F
|
||||
TYPE_LAST_INT = 0x1F
|
||||
|
||||
DATA_NULL_UNDEFINED = 0
|
||||
DATA_NULL_EMPTY = 1
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.type = self.TYPE_NULL
|
||||
@@ -564,18 +609,27 @@ class TypedValue(Stub):
|
||||
|
||||
@staticmethod
|
||||
def complexToDimension(data: int, metrics: DisplayMetrics) -> float:
|
||||
unit = data & 0xF
|
||||
value = (data >> 4) & 0xFFFFFF
|
||||
# Sign-extend
|
||||
if value & 0x800000:
|
||||
value = value - 0x1000000
|
||||
return TypedValue.applyDimension(unit, float(value), metrics)
|
||||
"""将复数维度值转换为像素值。
|
||||
复数值格式:bits 0-3=unit, bits 4-5=radix, bits 8-31=mantissa(有符号24位)"""
|
||||
unit = (data >> TypedValue.COMPLEX_UNIT_SHIFT) & TypedValue.COMPLEX_UNIT_MASK
|
||||
radix = (data >> TypedValue.COMPLEX_RADIX_SHIFT) & TypedValue.COMPLEX_RADIX_MASK
|
||||
mantissa = (data >> TypedValue.COMPLEX_MANTISSA_SHIFT) & TypedValue.COMPLEX_MANTISSA_MASK
|
||||
# 24 位有符号数符号扩展
|
||||
if mantissa & 0x800000:
|
||||
mantissa = mantissa - 0x1000000
|
||||
value = mantissa * TypedValue._RADIX_MULTS[radix]
|
||||
return TypedValue.applyDimension(unit, value, metrics)
|
||||
|
||||
@staticmethod
|
||||
def complexToFloat(data: int) -> float:
|
||||
value = (data & 0xFFFFFF00) >> 8
|
||||
exp = (data & 0xFF) - 150
|
||||
return float(value) * (10.0 ** exp)
|
||||
"""将复数值转换为浮点数(与 AOSP complexToFloat 一致)。"""
|
||||
radix = (data >> TypedValue.COMPLEX_RADIX_SHIFT) & TypedValue.COMPLEX_RADIX_MASK
|
||||
# mantissa 保持在原始位位置(左移 8 位),与 AOSP 一致
|
||||
mantissa = data & (TypedValue.COMPLEX_MANTISSA_MASK << TypedValue.COMPLEX_MANTISSA_SHIFT)
|
||||
# 处理符号(Java int 是有符号的,bit 31 为符号位)
|
||||
if mantissa & 0x80000000:
|
||||
mantissa = mantissa - 0x100000000
|
||||
return float(mantissa) * TypedValue._RADIX_MULTS[radix]
|
||||
|
||||
@staticmethod
|
||||
def complexToDimensionPixelOffset(data: int, metrics: DisplayMetrics) -> int:
|
||||
@@ -589,7 +643,9 @@ class TypedValue(Stub):
|
||||
return int(val - 0.5)
|
||||
|
||||
def getFloat(self) -> float:
|
||||
return float(self.data)
|
||||
"""将 data 字段按 IEEE 754 单精度浮点数解读(与 Float.intBitsToFloat 一致)。"""
|
||||
bits = self.data & 0xFFFFFFFF
|
||||
return struct.unpack('f', struct.pack('I', bits))[0]
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"TypedValue(type={self.type}, data={self.data})"
|
||||
|
||||
Reference in new issue
Block a user