feat: 全面完善API — 补全核心类方法、存根转真实实现、Exception体系扩展
核心类方法补全: - Activity: +20方法 (requestWindowFeature, setTitle/getTitle, onKeyDown/onKeyUp, enterPictureInPictureMode, getReferrer, isTaskRoot, navigateUpTo等) - Fragment: +15方法 (getChildFragmentManager, getParentFragment, requireContext/requireActivity, setMenuVisibility等) - Intent: +20方法 (getParcelableExtra, setComponent/getComponent, getDataString, getScheme, putExtras等) - View: +20方法 (setLabelFor, setRotationX/Y, setForeground, setBackgroundTintList等) - KeyEvent: +7方法 (getCharacters, isSystem, isPrintingKey, isModifierKey, startTracking等) - Paint: +12方法 (setStrokeCap/Join, getTextBounds, setBlendMode, setLetterSpacing等) - Notification.Builder: +10方法 (setProgress, setShowWhen, setOnlyAlertOnce, setSound等) 存根转真实实现: - TrafficStats: 读取 /proc/net/dev 返回真实网络流量 - RecyclerView.Adapter: 观察者模式触发通知 - BaseAdapter: 观察者模式触发通知 - ExifInterface: 使用PIL实现图片翻转/旋转 - Process: 使用os.kill实现进程信号 - FileUtils: 真实文件I/O - SharedPreferences: 监听器模式 - TelephonyManager.listen: 维护监听器列表 - ScrollView.smoothScrollTo: 更新滚动位置 Exception体系扩展: - 新增15个Exception/Error类 (ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchElementException, AssertionError, OutOfMemoryError, StackOverflowError, NoClassDefFoundError, UnsatisfiedLinkError, LinkageError, VerifyError, AbstractMethodError, IncompatibleClassChangeError, ExceptionInInitializerError) Math/System/Thread/StringBuilder/Integer增强: - Math: +20方法 (subtractExact, multiplyExact, toIntExact, floorDiv/floorMod, fma等) - System: getProperties/setProperties/mapLibraryName/getLogger - Thread: +10方法 (getUncaughtExceptionHandler, getAllStackTraces, getStackTrace, holdLock等) - StringBuilder: +7方法 (ensureCapacity, trimToSize, setLength, subSequence等) - Integer: +8静态方法 (compare, compareUnsigned, divideUnsigned, sum, max, min等) 修复: - app_fragment.py: 使用java.lang.IllegalStateException替代本地定义 - content_intent.py: Intent.setData/getScheme正确从Uri提取scheme - view_ext.py: KeyEvent继承view.KeyEvent获取所有KEYCODE常量 - __init__.py: 补全Fragment/KeyEvent/MotionEvent/TrafficStats/RecyclerView等导出 统计: 221模块, 3660类, 30826方法, 180217行
This commit is contained in:
1 parent
e316e18d98
commit
39b1da37c9
16 files changed
+1274
-107
No files matched your search
@@ -18,6 +18,7 @@ from .._core import (
|
||||
resolve_android_path, to_android_path,
|
||||
_sdcard_root, _app_data_dir, _package_name,
|
||||
)
|
||||
from ..java.lang import IllegalStateException
|
||||
|
||||
try:
|
||||
from .._linux_impl import IS_LINUX, LinuxNotify, LinuxShell, LinuxProcess, LinuxDisplay, LinuxUIAutomation, LinuxPower
|
||||
@@ -247,6 +248,108 @@ class Intent(Stub):
|
||||
def filterHashCode(self) -> int:
|
||||
return hash((self._action, self._data_str, self._type, self._package, self._component)) & 0x7FFFFFFF
|
||||
|
||||
def getParcelableExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def setComponent(self, component):
|
||||
self._component = component
|
||||
return self
|
||||
|
||||
def getComponent(self):
|
||||
return getattr(self, '_component', None)
|
||||
|
||||
def getDataString(self):
|
||||
data = self.getData()
|
||||
return str(data) if data else None
|
||||
|
||||
def getScheme(self):
|
||||
data = self.getData()
|
||||
if data:
|
||||
return data.getScheme()
|
||||
return None
|
||||
|
||||
def putExtras(self, src):
|
||||
if src._extras:
|
||||
if self._extras is None:
|
||||
self._extras = {}
|
||||
self._extras.update(src._extras)
|
||||
return self
|
||||
|
||||
def putIntegerArrayListExtra(self, name, value):
|
||||
if self._extras is None:
|
||||
self._extras = {}
|
||||
self._extras[name] = value
|
||||
return self
|
||||
|
||||
def putStringArrayListExtra(self, name, value):
|
||||
if self._extras is None:
|
||||
self._extras = {}
|
||||
self._extras[name] = value
|
||||
return self
|
||||
|
||||
def putParcelableArrayListExtra(self, name, value):
|
||||
if self._extras is None:
|
||||
self._extras = {}
|
||||
self._extras[name] = value
|
||||
return self
|
||||
|
||||
def getBundleExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def putBundleExtra(self, name, value):
|
||||
if self._extras is None:
|
||||
self._extras = {}
|
||||
self._extras[name] = value
|
||||
return self
|
||||
|
||||
def getParcelableArrayListExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def getStringArrayExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def getIntArrayExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def getBooleanArrayExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def getCharSequenceExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def getCharSequenceArrayListExtra(self, name):
|
||||
return self._extras.get(name) if self._extras else None
|
||||
|
||||
def removeCategory(self, category):
|
||||
if self._categories:
|
||||
self._categories.discard(category)
|
||||
return self
|
||||
|
||||
def setSelector(self, selector):
|
||||
self._selector = selector
|
||||
|
||||
def getSelector(self):
|
||||
return getattr(self, '_selector', None)
|
||||
|
||||
def setSourceBounds(self, bounds):
|
||||
self._source_bounds = bounds
|
||||
|
||||
def getSourceBounds(self):
|
||||
return getattr(self, '_source_bounds', None)
|
||||
|
||||
def makeMainActivity(self, component):
|
||||
self.addCategory("android.intent.category.LAUNCHER")
|
||||
self.setComponent(component)
|
||||
return self
|
||||
|
||||
def cloneFilter(self):
|
||||
new_intent = Intent(self.getAction())
|
||||
if self._categories:
|
||||
new_intent._categories = set(self._categories)
|
||||
if self._type:
|
||||
new_intent._type = self._type
|
||||
return new_intent
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ComponentName (forward reference)
|
||||
@@ -738,6 +841,62 @@ class Notification(Stub):
|
||||
n._extras = dict(self._extras)
|
||||
return n
|
||||
|
||||
def setProgress(self, max, progress, indeterminate):
|
||||
self._progress_max = max
|
||||
self._progress = progress
|
||||
self._progress_indeterminate = indeterminate
|
||||
return self
|
||||
|
||||
def setShowWhen(self, show):
|
||||
self._show_when = show
|
||||
return self
|
||||
|
||||
def setOnlyAlertOnce(self, onlyAlertOnce):
|
||||
self._only_alert_once = onlyAlertOnce
|
||||
return self
|
||||
|
||||
def setLocalOnly(self, localOnly):
|
||||
self._local_only = localOnly
|
||||
return self
|
||||
|
||||
def setSound(self, sound):
|
||||
self._sound = sound
|
||||
return self
|
||||
|
||||
def setVibrate(self, pattern):
|
||||
self._vibrate = pattern
|
||||
return self
|
||||
|
||||
def setLights(self, argb, onMs, offMs):
|
||||
self._light_color = argb
|
||||
self._light_on = onMs
|
||||
self._light_off = offMs
|
||||
return self
|
||||
|
||||
def setSortKey(self, sortKey):
|
||||
self._sort_key = sortKey
|
||||
return self
|
||||
|
||||
def setTimeoutAfter(self, timeoutMs):
|
||||
self._timeout_after = timeoutMs
|
||||
return self
|
||||
|
||||
def setColorized(self, colorize):
|
||||
self._colorized = colorize
|
||||
return self
|
||||
|
||||
def setUsesChronometer(self, usesChronometer):
|
||||
self._uses_chronometer = usesChronometer
|
||||
return self
|
||||
|
||||
def setShortcutId(self, shortcutId):
|
||||
self._shortcut_id = shortcutId
|
||||
return self
|
||||
|
||||
def setContent(self, views):
|
||||
self._content_view = views
|
||||
return self
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._channel_id = ""
|
||||
@@ -1355,6 +1514,90 @@ class Fragment(Stub):
|
||||
def unregisterForContextMenu(self, view):
|
||||
pass
|
||||
|
||||
def getChildFragmentManager(self):
|
||||
if not hasattr(self, '_child_fragment_manager'):
|
||||
from .app import FragmentManager
|
||||
self._child_fragment_manager = FragmentManager()
|
||||
return self._child_fragment_manager
|
||||
|
||||
def getParentFragment(self):
|
||||
return getattr(self, '_parent_fragment', None)
|
||||
|
||||
def onCreateOptionsMenu(self, menu, inflater):
|
||||
return False
|
||||
|
||||
def onPrepareOptionsMenu(self, menu):
|
||||
return False
|
||||
|
||||
def onOptionsItemSelected(self, item):
|
||||
return False
|
||||
|
||||
def onCreateContextMenu(self, menu, v, menuInfo):
|
||||
pass
|
||||
|
||||
def onContextItemSelected(self, item):
|
||||
return False
|
||||
|
||||
def onContextMenuClosed(self, menu):
|
||||
pass
|
||||
|
||||
def onConfigurationChanged(self, newConfig):
|
||||
pass
|
||||
|
||||
def onLowMemory(self):
|
||||
pass
|
||||
|
||||
def onHiddenChanged(self, hidden):
|
||||
self._hidden = hidden
|
||||
|
||||
def getLayoutInflater(self):
|
||||
return getattr(self, '_layout_inflater', None)
|
||||
|
||||
def onGetLayoutInflater(self, savedInstanceState):
|
||||
return self.getLayoutInflater()
|
||||
|
||||
def requireContext(self):
|
||||
if not hasattr(self, '_context') or self._context is None:
|
||||
raise IllegalStateException("Fragment " + self.__class__.__name__ + " not attached to a context")
|
||||
return self._context
|
||||
|
||||
def requireActivity(self):
|
||||
if not hasattr(self, '_activity') or self._activity is None:
|
||||
raise IllegalStateException("Fragment " + self.__class__.__name__ + " not attached to an activity")
|
||||
return self._activity
|
||||
|
||||
def requireView(self):
|
||||
if not hasattr(self, '_view') or self._view is None:
|
||||
raise IllegalStateException("Fragment " + self.__class__.__name__ + " view is null")
|
||||
return self._view
|
||||
|
||||
def requireFragmentManager(self):
|
||||
fm = getattr(self, '_fragment_manager', None)
|
||||
if fm is None:
|
||||
raise IllegalStateException("Fragment " + self.__class__.__name__ + " not associated with a fragment manager")
|
||||
return fm
|
||||
|
||||
def setMenuVisibility(self, menuVisible):
|
||||
self._menu_visible = menuVisible
|
||||
|
||||
def onMenuVisibilityChanged(self, menuVisible):
|
||||
pass
|
||||
|
||||
def postponeEnterTransition(self):
|
||||
pass
|
||||
|
||||
def startPostponedEnterTransition(self):
|
||||
pass
|
||||
|
||||
def getEnterTransition(self):
|
||||
return getattr(self, '_enter_transition', None)
|
||||
|
||||
def setEnterTransition(self, transition):
|
||||
self._enter_transition = transition
|
||||
|
||||
def onInflate(self, context, attrs, savedInstanceState):
|
||||
pass
|
||||
|
||||
|
||||
class FragmentTransaction(Stub):
|
||||
"""FragmentTransaction — 管理 Fragment 事务"""
|
||||
@@ -1875,6 +2118,102 @@ class Activity(Stub):
|
||||
return LinuxUIAutomation.press_key(key)
|
||||
return False
|
||||
|
||||
def requestWindowFeature(self, featureId):
|
||||
self._window_features = getattr(self, '_window_features', set())
|
||||
self._window_features.add(featureId)
|
||||
return True
|
||||
|
||||
def setTitle(self, title):
|
||||
self._title = title
|
||||
|
||||
def getTitle(self):
|
||||
return getattr(self, '_title', '')
|
||||
|
||||
def onKeyDown(self, keyCode, event):
|
||||
return False
|
||||
|
||||
def onKeyUp(self, keyCode, event):
|
||||
return False
|
||||
|
||||
def onTouchEvent(self, event):
|
||||
return False
|
||||
|
||||
def enterPictureInPictureMode(self):
|
||||
pass
|
||||
|
||||
def getReferrer(self):
|
||||
return getattr(self, '_referrer', None)
|
||||
|
||||
def setReferrer(self, referrer):
|
||||
self._referrer = referrer
|
||||
|
||||
def isTaskRoot(self):
|
||||
return True
|
||||
|
||||
def getChangingConfigurations(self):
|
||||
return getattr(self, '_changing_config', 0)
|
||||
|
||||
def navigateUpTo(self, intent):
|
||||
return True
|
||||
|
||||
def shouldUpRecreateTask(self, intent):
|
||||
return False
|
||||
|
||||
def getParentActivityIntent(self):
|
||||
return None
|
||||
|
||||
def onOptionsMenuClosed(self, menu):
|
||||
pass
|
||||
|
||||
def setVolumeControlStream(self, streamType):
|
||||
self._volume_control_stream = streamType
|
||||
|
||||
def getVolumeControlStream(self):
|
||||
return getattr(self, '_volume_control_stream', 0)
|
||||
|
||||
def getLocalClassName(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
def finishAndRemoveTask(self):
|
||||
self.finish()
|
||||
|
||||
def getLoaderManager(self):
|
||||
if not hasattr(self, '_loader_manager'):
|
||||
self._loader_manager = type('LoaderManager', (), {
|
||||
'initLoader': lambda *a: None,
|
||||
'restartLoader': lambda *a: None,
|
||||
'destroyLoader': lambda *a: None,
|
||||
'getLoader': lambda *a: None,
|
||||
})()
|
||||
return self._loader_manager
|
||||
|
||||
def onRetainNonConfigurationInstance(self):
|
||||
return None
|
||||
|
||||
def getLastNonConfigurationInstance(self):
|
||||
return getattr(self, '_last_non_config_instance', None)
|
||||
|
||||
def setProgressBarVisibility(self, visible):
|
||||
pass
|
||||
|
||||
def setProgress(self, progress):
|
||||
pass
|
||||
|
||||
def setSecondaryProgress(self, secondaryProgress):
|
||||
pass
|
||||
|
||||
def onSearchRequested(self):
|
||||
return False
|
||||
|
||||
def startSearch(self, initialQuery, selectInitial, appSearchData, globalSearch):
|
||||
pass
|
||||
|
||||
def startIntentSender(self, intent, fillInIntent, flagsMask, flagsValues, extraFlags):
|
||||
pass
|
||||
|
||||
def startIntentSenderForResult(self, intent, requestCode, fillInIntent, flagsMask, flagsValues, extraFlags):
|
||||
pass
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Service
|
||||
|
||||
Reference in new issue
Block a user