當前位置:首頁 » 安卓系統 » androidfindclass

androidfindclass

發布時間: 2022-12-11 08:34:06

㈠ Android-類載入

雙親委託機制

類在進行類載入的時候,把載入任務託管給父類載入器,如能載入成功,則返回,否則依次向子類載入器遞歸嘗試類載入。

意義:

①避免類的重復載入,父類載入已載入該類時,子ClassLoader就沒有必要載入一次了。

②安全性,防止核心API被隨意篡改。

ClassLoader

ClassLoader本身是一個抽象方法。它的主要實現類有BootClassLoader、PathClassLoader、DexClassLoader.

BootClassLoader:用於載入Android Framwork層(SDK)的class文件

PathClassLoader:用於Android應用程序載入器,可以載入指定的dex和jar、zip、apk中的classes.dex(系統使用)

DexClassLoader:用於載入指定的dex和jar、zip、apk中的classes.dex。(供開發者使用)

拓展:

在API26之前。

optimizedDirectory 參數就是dexopt的產出目錄(odex)。那 PathClassLoader 創建時,這個目錄為null,就

意味著不進行dexopt?並不是, optimizedDirectory 為null時的默認路徑為:/data/dalvik-cache。

在API26之後DexClassLoader也取消了optimizedDirectory

熱修復相關

LoadClass:

findClass:PathClassLoader和DexClassLoader的父類BaseDexClassLoader中實現findClass。

BaseDexClassLoader中

PathClassLoader載入過後,pathlist 中存在一個Element數組,Element類中存在一個dexFile成員表示dex文件,即:APK中有X個dex,則Element數組就有X個元素。

總結:

可能看到這里我們比較亂了,理一下。一個類的載入經歷了哪些。我們以PathClassLoader為例。

①載入一個類的時候,首先通過Class緩存尋找是否已經載入過該類。參考抽象類的loadClass方法。

②若在緩存中未找到該類,則交由父載入器載入該類。參考抽象類的loadClass方法。

③調用父載入器PathClassLoader的父類BaseDexClassLoader實現的findClass方法載入該類。

④PathClassLoader在初始化的時候調用父構造方法實例化DexPathList屬性,DexPathList屬性初始化時構造方法內通過makePathElements(或makeDexElements 不同API可能不同)載入APK內的dex文件生成Element數組。

⑤BaseDexClassLoader實現的findClass方法中順序循環已存在的Element數組,通過Element中的DexFile載入類。。

⑥未找到,拋出類未找到異常。

熱修復(multide 形式(thinker、qfix))

熱修復的原理。我們只需在應用啟動的時候,一般是在application方法中(因為class載入首先從緩存中載入),在應用啟動後,經過PathClassLoader載入過後所有的類都在 pathList的Element 數組,把生成的Elment數組插入到PathList的Element數組的最前方。在載入類的時候就只會載入到我們需要更新的類了,因為是順序尋找,找到就返回。(先從我們補丁的dex文件生成的element尋找,找不到再從APK的dex生成的element種尋找)。

熱修復基本思路總結:

①獲取到當前引用的PathClassLoader

②反射獲取其中DexPathList屬性:DexPathList pathList.

③獲取到補丁包path.dex文件的Element[]數組 pElements。參考PathClassLoader怎麼把dex文件轉換為Element數組的。於是我們反射執行DexPathList 中的makePathElements方法(視API而定)傳入dex路徑得到補丁包的element數組。

④獲取pathList的dexElements數組。

⑤把補丁包的pElements數組合並到pathList的dexElements數組的前方,即newElements=pElements+dexElements

⑥反射賦值把newElements替換掉pathList的dexElements

熱修復沒這么簡單,還需考慮混淆,API版本不同導致的使用makePathElements方法或makeDexElements方法等因素。

熱修復(InstantRun 形式(Robust))待了解。

㈡ android開發,改了包出現如下錯誤

Unable to get provider database.eHotelProviders
java.lang.ClassNotFoundException: database.eHotelProviders
你把包名換了,相應Class文件中的package也要修改,相關的都得修改,你這不是提示找不到calss文件的異常么。

㈢ Android 插件化

原理:實現原理上都選擇盡量少的hook,通過在manifest上預埋一些組件實現四大組件的插件化。其中Small更形成了一個跨平台、組件化的框架。

VirtulApp:
能夠完全模擬app的運行環境,能夠實現免安裝應用和雙開技術。
Atlas:
阿里出品,號稱是一個容器化框架,結合了組件化和熱更新技術。

Android中有兩種類載入器,DexClassLoader和PathClassLoader,它們都繼承於BaseDexClassLoader。

兩者的區別:DexClassLoader多了一個optimizedDirectory的路徑參數,這個目錄必須是內部存儲路徑,用於緩存系統創建的Dex文件。

所以我們可以使用DexClassLoader去載入外部Apk中的類。

ClassLoader調用loadClass方法載入類採用了雙親委託機制來避免重復載入類。
首先,ClassLoader會查看自身已經載入的類中是否已經存在此類,如不存在,然後,則會使用父類來載入此類,如不能成功載入,則會使用自身重載於BaseDexClassLoader的findClass()方法來載入此類。

DexClass的DexPathList在DexClass的構造器中生成,findClass()方法則是從DexPathList下面找出對應的DexFile,循環DexElements,通過dexElement.dexFile取出對應的DexFile,再通過DexFile.loadClassBinaryName()載入對應的類。

作用:使用插件DexClassLoader載入出需要的類。

通過每一個插件的DexClassLoader載入出自身所需要的類,當每一個插件需要載入相同的類庫時,可採用該類庫的不同版本來使用。

通過把每一個插件的pathList(DexFile)合並到主app的DexClassLoader上,來使各個插件和主app直接能夠相互調用類和方法,並且各個插件中相同的功能可以抽取出來作為一個Common插件供其它插件使用。

插件調用主工程
在ClassLoader構造時指定主工程的DexClassLoader為父載入器即可直接調用主工程中的類和方法。
主工程調用插件
如果是多DexClassLoader的情況,則需要通過插件的DexClassLoader載入對應的類並反射調用其方法。此種情況,主工程一般會在一個統一的地方對訪問插件中的類和方法做一些訪問許可權的管理及配置。

如果是單DexClassLoader的情況,則可以直接調用插件中的類和方法。但是當多個插件引用的庫的版本不同時,會出現錯誤,因此,建議採用Gradle版本依賴管理統一處理主工程及各個插件的庫依賴。

Android通過Resource來載入資源,只要有插件apk,就可以使用assertManager.addAssertPath(apkPath)的方式來生成assertManager,再使用其new出對應的Resource對象即可。

注意:由於AssertManager並不是Public,所以需要通過反射的方式去調用它。並且由於一些Rom對Resource的處理,所以,需要兼容處理。

有2種處理方式:

產生的原因:由於主工程和各個插件引用的Resource id重復產生的沖突。

解決思路:Android中的資源在系統中是以8位16進制0XPPTTRRRR的方式存在,其中PP即是資源區分的區域(Android系統只用它來區分系統資源和應用資源),只要讓每一個插件的PP段取不同的值即可解決資源id沖突的問題。
具體解決方式:

1.修改aapt源碼編譯期修改PP段。
2.修改Resource的arsc文件,其中的每一條都包含了資源id和映射路徑。

Activity的處理最為復雜,有兩種處理方式:
1.ProxyActivity的方式。
2.預埋StubActivity,hook系統啟動Activity的過程。

原理:VirtualAPK通過替換了系統的Instrumentation,hook了Activity的啟動和創建,省去了手動管理插件Activity生命周期的繁瑣,讓插件Activity像正常的Activity一樣被系統管理,並且插件Activity在開發時和常規一樣,即能獨立運行又能作為插件被主工程調用。

Android插件化方向主要有2個方向:

Android 插件化

㈣ android插件化(四)Hook載入插件APK(ClassLoader方式)

前面插件化一和二說了下插樁式載入未安裝的APK,主要是重寫了getResource和getClassloader兩個方法來實現的。以及每個組件要實現一個介面,通過介面注入上下文來達到它的生命周期。

那麼插樁式和hook式的實現方式有什麼不同呢?

插樁式是怎麼載入到插件中的class文件呢,是通過將將APK轉化成插件的Classloader,然後想要載入插件的class文件,我們的去拿這個插件的classloader去loadClass。所以是有一個中間者的。

hook式呢是將插件apk融入到了我們的宿主apk,那直接在裡面就可以直接loadClass了,在不用這個插件的ClassLoader了,這樣的話對於插件和宿主就沒什麼區別了,不像插樁式有一個中間者。

那麼要實現hook式 就要知道android中一個class文件式怎樣被載入到內存中去的。其實就是通過PathClassLoader來載入的。

那麼我們先看下ClassLoader

任何一個java程序都是由一個或者多個class組成的,在程序運行時,需要將class文件載入到JVM中才可以使用,負責載入這些class文件的就是java的類載入機制。CLassLoader的作用就是載入class文件提供給程序運行時使用,每個Class對象內部都有一個ClassLoader來標示自己是有那個classLoade載入的。

Android app的所有的java文件都是通過PathClassLoader來載入的,那麼它的父類是BaseDexClassLoader,還有一個兄弟類是DexClassLoader,那麼他們有什麼區別呢。

從上面可以看出這兩個類的構造函數不同。(在26的源碼中DexClassLoader中的optimizedDirectory也廢棄了)

PathClassLoader:用於Android應用程序類載入器。可以載入指定的dex,以及jar、zip、apk中的classes.dex

DexClassLoader:載入指定的dex以及jar、zip、apk中的classes.dex。

可以看到創建ClassLoader的時候需要接收一個CLassLoader parent的參數,這個parent的目的就在於實現類載入的委託。

某個類載入器在接到載入類的請求時,首先將載入任務委託給父類載入器,一次遞歸,如果父載入器可以完成載入任務,那麼就返回,只有當父載入器無法完成載入任務時,才自己去載入。

因此我們自己創建的ClassLoader:newPathClassLoader("/sdcard/xx.dex",getClassLoader()),並不僅僅只能載入我們的xx.dex中的class。

需要注意的是,findBootstrapClassOrNull 這個方法,當parent為null的時候,去這個BootCLassLoader進行載入,

但是在Android當中的實現:

所以new PathClassLoader("/sdcard/xx.dex",null),是不能載入Activity.class的。

上面分析了載入了一個class,是利用了雙親委託機制,那麼要是都找不到那就開始調用自己的findCLass方法

在ClassLoader類中findClass:

任何ClassLoader的子類,都可以重寫loadClass和findClass。如果你不想使用雙親委託,就重寫loadClas修改實現,重寫findClass則表示在雙親委託機制下,父ClassLoader都找不到class的情況下,定義自己去查找一個class。

而我們的PathClassLoader會自己負責載入Activity這樣的類,利用雙親委託父類去載入activity,而我們的PathClassLoader沒有重寫findClass,是在它的父類裡面。因此我們可以看看父類的findClass是如何實現的。

可以看到載入PathClassLoader載入class,轉化為從DexPathList中載入class了,那麼我們看看DexPathList中的findClass

那麼從上面分析得到

到這里我們想要載入一個插件的apk ,其實最終載入的是一個dex文件(先說class文件,載入資源後面說),有沒有辦法吧這個dex文件給轉化成一個 Element 對象,給放到 Elemeng數組 當中,這樣直接就可以載入我們插件中的類了。

1、首先我們肯定是要得到插件APK的的中DexPathList對象中的dexElement數組

2、插件的dexElements數組我們拿到了,那麼是不是要開始拿我們系統裡面的 ,我們反射獲取,和上面的一樣。

3、上面我們獲取到了系統和我們插件的dexElement數組,然後我們將這個數組合並到一個新的數組裡面去,並且給注入到系統裡面

至此,載入插件的一個流程基本就完成了。但是上面只是處理了class文件,沒有處理資源。資源的話我們也是採用hook的方式去實現

在宿主的Application中hook這個方法,然後去重寫getAsserts和getResources兩個方法:

然後在插件的BaseActivity中繼續重寫getAssets和getResources兩個方法

這樣就可以完成hook式載入一個未安裝的APK了。至此基本就完成了插樁式和Hook式插件化的基本實現。(後面幾篇是優化)。

㈤ android開發 如何在jni本地代碼 訪問自己寫的類。如何使用env->findclass

jclass GpsInfoClass = env->FindClass("com/parser/GPSINFO");
jfieldID ID_bValid = env->GetFieldID(GpsInfoClass,"bValid","I");
jfieldID ID_bSpeed = env->GetFieldID(GpsInfoClass,"bSpeed","I");
env->SetIntField(_obj,ID_bValid,(jint)info.bValid);
env->SetIntField(_obj,ID_bSpeed,(jint)info.bSpeed);
return _obj;
以上就可以了。但是不知道你的BYTE是自定義的什麼類型,如果是char之類的,就另外想辦法轉換成jint。其中 _obj 變數是public native GPSINFO getGpsInfo();這個本地方法在C代碼中的參數:JNIEXPORT jobject JNICALL Java_com_parser_GPSINFO_ getGpsInfo(JNIEnv *env, jobject _obj)

㈥ 【Android】Android中的類載入

前文: 【Java】ClassLoader與雙親委派機制

Android中的類載入器有三種, DexClassLoader 、 PathClassLoader 、 BootClassLoader 。
其中 BootClassLoader 是系統啟動時預載入常用類的,一般使用不到。 DexClassLoader 、 PathClassLoader 都是繼承自 BaseDexClassLoader 。
但 DexClassLoader 和 PathClassLoader 並沒有重寫 BaseDexClassLoader 中的任何方法,所以源碼只需要看 BaseDexClassLoader 即可。

由於Android SDK並沒有包含 BaseDexClassLoader ,所以需要到源碼查詢網站查詢源碼,如下:

復制這個java文件到對應源碼文件夾下就可以在Android Studio中查看了。

通過調試可以看到,Android中普通類的載入器其實是 PathClassLoader 。追蹤 PathClassLoader.findClass 方法,即可獲取Android的類載入過程:

PathClassLoader.findClass -- 繼承自 --> BaseDexClassLoader.findClass()
-> BaseDexClassLoader.pathList.findClass()
-> DexPathList.dexElements.foreach { element.findClass() }
-> Element.findClass()
-> Element.dexFile.loadClassBinaryName()
-> DexFile.defineClass()

即類載入過程通過 BaseDexClassLoader.findClass 、 DexPathList.findClass 、 Element.findClass 、 DexFile.loadClassBinaryName ,最終會落到 DexFile.defineClass 方法中,然後就交給native層了。

其中需要注意的是,在 BaseDexClassLoader.findClass 的開頭有這么一段:

這段是在Android 10新加入的,據稱是為了實現 shared library 功能的,在之前的版本中沒有這一段。

在上一節中知道了,類載入的流程如下:
BaseDexClassLoader.findClass() ->
BaseDexClassLoader.pathList.findClass() ->
DexPathList.dexElements.foreach { element.findClass() } ->
Element.findClass() -> ...

看 DexPathList.findClass 方法:

可以發現, DexPathList 載入類的方法是遍歷 dexElements 數組依次載入,知道獲取到值為止。所以可以通過修改這個數組,把新的dex文件放在數組的前面,使其載入修改後的類,從而實現熱修復。

根據以上原理,寫下這個工具類,有效性待驗證:

㈦ Android類載入機制

Android手寫熱修復(一)--ClassLoader

我們平時編寫的 .java 文件不是可執行文件,需要先編譯成 .class 文件才可以被虛擬機執行。所謂類載入是指通過 類載入器 把class文件載入到虛擬機的內存空間,具體來說是方法區。類通常是按需載入,即第一次使用該類時才載入。

首先,Java與Android都是把類載入到虛擬機內存中,然後由虛擬機轉換成設備識別的機器碼。但是由於二者使用的虛擬機不同,所以在類載入方面也是有所區別的。Java的虛擬機是JVM,Android的虛擬機是dalvik/art(5.0以後虛擬機是art,是對dalvik的一種升級)。 Java虛擬機運行的是class文件,而Android 虛擬機運行的是dex文件。 dex其實是class文件的集合,是對class文件優化的產物,是為了避免出現重復的class。

從上面的講解中,我們已經知道我們平時寫的類是被 類載入器 載入盡虛擬機內存才能運行。下面就通過Framework源碼來為大家講解Android中最主要的5個類載入器。

在Activity做個簡單驗證:

結果:

可以看出系統類由BootClassLoader載入,apk中的類由PathClassLoader載入,PathClassLoader的父類載入器是BootClassLoader。如果暫時不能理解父類載入器是什麼,沒關系,後面講雙親委託機制的時候會理解的。

下面的源碼解析基於 Android SDK API28 ,這幾個類載入器(除了ClassLoader)沒辦法直接在AS上查看源碼,AS搜索到的是反編譯的class的內容,是不可信的,為大家推薦一個在線工具查看, 在線查看Android Framework源碼 。

用來載入本地文件系統上的文件或目錄,通常是用來載入apk中我們自己寫的類,而像 Activity.class 這種系統的類不是由它載入。注意:這里,並不像很多網上文章說的那樣只能載入apk,本地的其他目錄的文件也是可以的,這一點我會在後面驗證說明。

也是被用來載入 jar 、apk、dex,通常用來載入未安裝到應用中的文件。注意,它需要一個應用私有的可寫的目錄來存放優化後的dex文件。千萬不要選擇外部存儲路徑,因為這樣可能會導致你的應用遭到注入攻擊。

關於dex文件優化,可能很多人還是不理解,水平有限,我簡單解釋一下,

構造器參數解釋:

關於optimizedDirectory:
1、這是dex優化後的路徑,它必須是一個應用私有的可寫的目錄否則會存在注入攻擊的風險;
2、這個參數在API 26(8.0)之前是有值的,之後的話,這個參數已經沒有影響了,因為在調用父構造器的時候這個參數始終為null,也就是說Android 8.0 以後DexClassLoader和PathClassLoader基本一樣的來;
3、在載入app的時候,apk內部的dex已經執行過優化了,優化之後放在系統目錄/data/dalvik-cache下。

這個構造器的關鍵是初始化了一個DexPathList對象,這個是後面載入class的關鍵類。

這個構造方法等關鍵是通過 makeDexElements() 方法來獲取Element數組,這個Element數組非常關鍵,後面查找class就會用到它,也是熱修復的關鍵點之一。

splitDexPath(dexPath) 方法是把dexPath目錄下的所有文件轉換成一個File集合,如果是多個文件的話,會用 : 作為分隔符。

makeDexElements()

小結一下,這個方法就是把指定目錄下的文件apk/jar/zip/dex按不同的方式封裝成Element對象,然後按順序添加到Element[]數組中。

DexPathList#loadDexFile()

可以看到 DexFile 最終是調用了openDexFile、native方法openDexFileNative去打開Dex文件的,如果outputName為空,則自動生成一個緩存目錄,具體來說是 /data/dalvik-cache/[email protected] 。openDexFileNative這個native方法就不具體分析了,主要是對dex文件進行了優化操作,將優化後得odex文件通過mmap映射到內存中。感興趣的同學可以參考:
《DexClassLoader和PathClassLoader載入Dex流程》

現在在回頭看看DexClassLoader與PathClassLoader的區別。DexClassLoader可以指定odex的路徑,而PathClassLoader則採用系統默認的緩存路徑,在8.0以後沒有區別。

ClassLoader是一個抽象類,有3個構造方法,最終調用的還是第一個構造方法,主要功能是保存實現類傳入的parent參數,也就是父類載入器。ClassLoader的實現類主要有2個,一個是前面講過的BaseDexClassLoader,另一個是BootClassLoader。

BootClassLoader是ClassLoader的內部類,而且繼承了ClassLoader。

這是載入一個類的入口,流程如下:
1、 先檢查這個類是否已經被載入,有的話直接返回Class對象;
2、如果沒有載入過,通過父類載入器去載入,可以看出parent是通過遞歸的方式去載入class的;
3、如果所有的父類載入器都沒有載入過,就由當前的類載入器去載入。

通常我們自己寫的類是通過當前類載入器調用 findClass 方法去載入的,但是在 ClassLoader 中這是個空方法,具體的實現在它的子類 BaseDexClassLoader 中。

BaseDexClassLoader # findClass

可以看到是通過pathList去查找class的,這個對象其實之前講過,它是在BaseDexClassLoader 的構造方法中初始化的,它實際上是一個 DexPathList 對象。

DexPathList # findClass()

對Element數組遍歷,再通過Element對象的 findClass 方法去查找class,有的話就直接返回這個class,找不到則返回null。 這里可以看出獲取Class是通過DexFile來實現的,而各種類載入器操作的是Dex。Android虛擬機載入的dex文件,而不是class文件。

1、載入一個類是通過雙親委託機制來實現的。
2、如果是第一次載入class,那是通過 BaseDexClassLoader 中的findClass方法實現的;接著進入 DexPathList 中的findClass方法,內部通過遍歷Element數組,從Element對象中去查找類;Element實際上是對Dex文件的包裝,最終還是從dexfile去查找的class。
3、一般app運行主要用到2個類載入器,一個是PathClassLoader:主要用於載入自己寫的類;另一個是BootClassLoader:用於載入Framework中的類;
4、熱修復和插件化一般是利用DexClassLoader來實現。
5、PathClassLoader和DexClassLoader其實都可以載入apk/jar/dex,區別是 DexClassLoader 可以指定 optimizedDirectory ,也就是 dex2oat 的產物 .odex 存放的位置,而 PathClassLoader 只能使用系統默認位置。但是在8.0 以後二者是沒有區別的,只能使用系統默認的位置了。

這張圖來源於:
Android虛擬機框架:類載入機制

在類載入流程分析中,我們已經知道,查找class是通過DexPathList來完成的,實際上DexPathList最終還是遍歷其Element數組,獲取DexFile對象來載入Class文件。 由於數組是有序的,如果2個dex文件中存在相同類名的class,那麼類載入器就只會載入數組前面的dex中的class。如果apk中出現了有bug的class,那隻要把修復的class打包成dex文件並且放在 DexPathList 中Element數組`的前面,就可以實現bug修復了 。下一篇為大家帶來的手寫熱修復。

Android類載入機制的細枝末節
從JVM到Dalivk再到ART(class,dex,odex,vdex,ELF)
類載入機制系列2——深入理解Android中的類載入器
Android 熱修復核心原理,ClassLoader類載入

㈧ Android JNI 筆記 | GetObjectClass、FindClass和GetMethodID

  jclass GetObjectClass(jobject obj)

使用小栗子 (其中的 GetMethodID 函數請往下看) :

jclass FindClass(const char* name)

小栗子:

  jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
 參數一: jclass 查找到的java類
 參數二: const char* name 方法名

 參數三: const char* sig 方法的返回值

小栗子:

㈨ android sensor信息能不能hook

首先我們可以用Xposed框架來hook計數感測器的隊列函數dispatchSensorEvent(),這個函數在android.hardware.SystemSensorManager$SensorEventQueue這個類中。隨後在微信運動每次詢問行走步數的時候,我們先獲取當前步數,然後在目前的步數的基礎上加1000步,然後將信息返回給微信運動。微信運動就會誤以為我們運動了1000步,從而達到了欺騙的效果。
關鍵代碼如下:
首先hook android.hardware.SystemSensorManager$SensorEventQueue這個類的dispatchSensorEvent()函數:
final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue",lpparam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook()

接著我們在記步感測器把步數信息返回給微信運動之前,將返回的步數加上1000步:
protected void beforeHookedMethod(MethodHookParam param) throws
Throwable {
XposedBridge.log(" mzheng Hooked method: " + param.method);
((float[]) param.args[1])[0]=((float[]) param.args[1])[0]+1000*WechatStepCount;
WechatStepCount+=1;


另外我們還可以使用一些感測器的介面獲取一些數據的信息:
Sensor ss = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log(" SensorEvent: sensor=" + ss);

比如說x就代表開機以來行走的步數,timestamp是獲取步數時候的時間戳等。
另外,我們不僅在android上可以hook計步器,在iOS上也是可以通過越獄後hook iHealth的API介面達到同樣的作弊效果,有興趣的同學可以繼續研究。

熱點內容
c是高級語言嗎 發布:2025-03-17 12:16:31 瀏覽:521
python泛型 發布:2025-03-17 12:15:01 瀏覽:480
編程貓被盜 發布:2025-03-17 12:02:18 瀏覽:130
海關鎖密碼箱如何設置新密碼 發布:2025-03-17 11:53:50 瀏覽:559
農業卡號的密碼在哪裡改 發布:2025-03-17 11:48:57 瀏覽:965
楊瀾超級訪問 發布:2025-03-17 11:47:17 瀏覽:237
資料庫無損連接 發布:2025-03-17 11:47:16 瀏覽:13
memcachephp類 發布:2025-03-17 11:40:04 瀏覽:829
哈夫曼編碼演算法實現 發布:2025-03-17 11:23:31 瀏覽:385
錄音機可以存儲信息嗎 發布:2025-03-17 11:13:32 瀏覽:174