android共享庫
Ⅰ android shared library已停用
android中的所有應用程序都無法禁用。
每一個模塊名稱必須惟一,且不含任何空格。構建系統在生成最終共享庫文件時,會將正確的前綴和後綴自動添加到您分配給LOCAL_MODULE的名稱。例如,上述示例會致使生成一個名為libhello-jni.so的庫。
若是模塊名稱的開頭已經是lib,則構建系統不會附加額外的前綴lib;而是按原樣採用模塊名稱,並添加.so擴展名。所以,好比原來名為libfoo.c的源文件仍會生成名為libfoo.so的共享對象文件。此行為是為了支持Android平台源文件從Android.mk文件生成的庫,全部這些庫的名稱都以lib開頭。
Ⅱ 安裝安卓軟體時提醒說沒有該應用所需的共享庫是怎麼回事
共享庫不存在或失效,是因為你所升級的軟體與你手機的系統不兼容,必須裝回以前那個版本,比如說你的軟體升級到1.1版本出現了共享庫不存在或失效,無法安裝,你只要裝回1.0版本的那個軟體就可以了。
Ⅲ android中java靜態庫和java共享庫有什麼區別
程序編制一般需經編輯、編譯、鏈接、載入和運行幾個步驟。在我們的應用中,有一些公共代碼是需要反復使用,就把這些代碼編譯為「庫」文件;在鏈接步驟中,連接器將從庫文件取得所需的代碼,復制到生成的可執行文件中。這種庫稱為靜態庫,其特點是可執行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。
為了克服這個缺點可以採用動態鏈接庫。這個時候鏈接器僅僅是在可執行文件中打上標志,說明需要使用哪些動態連接庫;當運行程序時,載入器根據這些標志把所需的動態鏈接庫載入到內存。
另外在當前的編程環境中,一般都提供方法讓程序在運行的時候把某個特定的動態連接庫載入並運行,也可以將其卸載(例如Win32的LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose())。這個功能被廣泛地用於在程序運行時刻更新某些功能模塊或者是程序外觀。
與普通程序不同的是,Java程序(class文件)並不是本地的可執行程序。當運行Java程序時,首先運行JVM(Java虛擬機),然後再把Java class載入到JVM里頭運行,負責載入Java class的這部分就叫做Class Loader。通常class文件僅在需要使用時才載入。 這本身就是一種動態鏈接。
Java作為一種天生的動態鏈接語言,無法支持靜態鏈接。但C語言的靜態庫除了靜態鏈接的概念外,還隱含了一層意思,即庫中的代碼會打包到可執行文件中。JAVA中的JAR某種程度上類似一個可執行文件或庫,借用C語言中靜態庫和動態庫的概念,這里把最終會合並到生成的JAR文件中的JAR包叫靜態庫,反之僅僅在編譯中使用,並不打包到生成的JAR包中,運行時需系統自行提供的JAR包叫動態庫。
C的靜態鏈接只把需要的代碼復制過來,而Java用類似Fat Jar的方法,把所有的依賴庫打包到最後的庫中,眉毛鬍子一把抓。這個問題可以用ProGuard解決,用它自己的話說是 It detects and removes unused classes, fields, methods, and attributes。
Eclipse中對JAR包的使用方式有兩種,library和user libraries,其中library在工程中通過add jars...或add external jars...添加,出現在Referenced Libraries中,而user libraries需要在工作空間中管理,再在工程中通過add library...添加。這兩種使用方式本身並沒有靜態庫和動態庫的區別,需要在打包或部署時再行指定。但user libraries的方式明顯更方便管理多個工程共同使用的多個庫,而系統庫往往都有這種特性。
android的apk比JAR更類似可執行程序,而且因為標准庫隱藏了很多功能,我們常常需要使用自己構建的系統庫來編譯。但android的ADT工具並沒有提供是否將library或user libraries打包的選項。根據我的經驗,ADT默認將library打包到apk中,而user libraries則僅用於編譯,運行時再請求系統載入相關類。哪位同學有更明確的信息,還望指教,我短期內恐怕不會有時間去研究這個問題。
因此,可以這么說,在android中,library用來添加靜態庫,而user libraries用來管理動態庫。千萬不能弄錯了,如果把靜態庫錯誤地加入動態庫,運行時會出現找不到對應的class的錯誤,但因為Java語言的動態鏈接機制,只有運行到庫中代碼時才會出錯;反之,如果把動態庫做成了靜態庫,問題就更隱蔽了,可能只是dex文件特別大,而沒有其它問題,也可能因載入了錯誤版本的系統代碼,出現一些稀奇古怪的問題。慎之,慎之...
附:向eclispe中添加user Libraries的步驟:
1。點擊eclipse的window菜單,選擇「Preference」
2。在preferences窗口中選擇java->User Libraries,然後點擊窗口右邊的New...按鈕,在彈出的子窗口中輸入user library的名稱,此時在user libraries窗口中會出現新加的library名稱。
3。向該user library中添加jar包。選中my_lib,然後點擊Add JARS...按鈕,選擇你要添加的jar後,點擊「打開」按鈕,則my_lib庫中就會出現你剛添加的jar文件信息。
4。最後點擊窗口下的「OK」按鈕,完成user library的添加和其jar的添加。
Ⅳ 安卓平台屬於動態庫操作嗎
屬於
靜態庫全稱靜態鏈接庫,動態庫全稱動態鏈接庫,看到全稱就知道什麼意思了吧?也就是說在鏈接的時候才會用到的庫,只有C/C++、OC語言才會有鏈接過程,Java沒有。在Android中說到靜態庫和動態庫,一般說的都是C/C++代碼,我們知道在android中是通過jni技術訪問到C代碼的,我們會把C/C++打包成so文件,這個就是動態庫(共享庫)。如果我們想要使用的C庫是.a形式的靜態庫時,我們要把.a包裝成so庫,具體網上有方法。個人感覺在java語言中討論靜態庫和動態庫就是個偽概念,java是的編譯結果是位元組碼文件,不是二進制文件,而且沒有鏈接的過程,jvm在解釋執行java代碼的時候調用C++代碼只能是動態的。在C++和object C開發中,用編譯鏈接的過程,靜態庫在鏈接過程中,會和自己寫的源代碼打到一塊,多個程序多個靜態庫。動態庫不會打到一塊,如果有共享情況的話,系統只會載入一次。OC的代碼處理過程是很復雜的,有預處理、編譯、鏈接過程,預處理就是處理宏什麼的,編譯這個過程就很復雜了,有編譯前端和編譯後端,編譯稱機器碼(中間還會有匯編的過程),鏈接就是鏈接動態庫或者靜態庫。Android(java)代碼處理過程就很簡單啦,畢竟是運行在虛擬機上的。沒有所謂的預處理,直接編譯,這里的編譯也就是把java代碼轉化成位元組碼,這個編譯和OC中的編譯可不是一個概念,只不過也這么叫而已。後續Aandroid還會用dex工具把.class打包成.dex,不同的VM模式(5.0以後都是ART)會對.dex進行不同的優化,具體看Android 編譯到運行APK過程總結。需要提一下的是,ART採用AOT和JIT技術,在安裝或者運行的時候,會把位元組碼轉化成機器碼,這個機器碼也會受VM控制的,具體看Android之Dalvik 、ARTC/C++、Object C屬於編譯型語言,這是毋庸置疑的,因為它們都會在生成安裝包之前編譯成機器碼。
Ⅳ Android 怎麼自定義共享庫
LOCAL_PATH := $(call my-dir)//標准mk語句,指編譯路徑,所有mk文件第一句都是這個 /**這個模塊表示引用了一個本地的靜態庫 include $(CLEAR_VARS) //清除各種變數,因為這些變數是靜態全局的,如果清除,下次編譯時又會用到這些變數造成出錯 LOCAL_MODULE := libopencore-amrnb //本地靜態庫模塊的名字,這個名字在下面編譯jni時需要引用 LOCAL_SRC_FILES := lib/libopencore-amrnb/smfwuxiao/article/details/6591927 NDK r5 開始支持預編譯共享庫。預編譯共享庫就是從其他地方獲得源碼編譯出的共享庫,而不是Android系統自帶的。方法如下: 1、聲明共享庫模塊 把共享庫聲明為一個獨立模塊。假如 libfoo.so 與 Android.mk 位於同一目錄。則 Android.mk 應該這樣寫: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt # 模塊名 LOCAL_SRC_FILES := libfoo.so # 模塊的文件路徑(相對於 LOCAL_PATH) include $(PREBUILT_SHARED_LIBRARY) # 注意這里不是 BUILD_SHARED_LIBRARY 這個共享庫將被拷貝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (strip過的) 2、在其他模塊中引用這個共享庫 在 Android.mk 中,將這個共享庫的模塊名加入 LOCAL_STATIC_LIBRARIES (靜態庫)或 LOCAL_SHARED_LIBRARIES (動態庫) 例如, 使用 libfoo.so 的方法: include $(CLEAR_VARS) LOCAL_MODULE := foo-user LOCAL_SRC_FILES := foo-user.c LOCAL_SHARED_LIBRARY := foo-prebuilt include $(BUILD_SHARED_LIBRARY) 3、為共享庫導出頭文件 這個共享庫一般有相應的頭文件,比如 libfoo.so 就有 foo.h。 一個簡單方法(在Android.mk中寫): include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) 這樣,使用該共享庫的模塊就會在它的 LOCAL_C_INCLUDES 變數加入該頭文件搜索路徑。 4、調試共享庫 建議你的共享庫保留調試信息。 $PROJECT/libs/<abi> 目錄下的共享庫都是 strip 之後的(沒有調試信息)。有調試信息的版本可被ndk-gdb使用。 5、共享庫 ABI 你的共享庫與目標系統ABI的兼容性很重要。 請檢查 TARGET_ARCH_ABI,有以下值: armeabi => ARMv5TE 以上 armeabi-v7a => ARMv7 以上 x86 => x86 建議: armeabi ABI 可以運行在所有 ARM CPU 上。
Ⅵ android 怎麼自定義共享庫
在源碼根目錄下有個 vendor (供應商) 目錄,專門用於存放各個供應商的會有代碼。其中有一個個 sample 目錄,這是 Google 用於示範如何編寫自定義共享庫的示例,它展示了自定義共享庫、JNI 調用、對庫的使用方法及皮膚定製等功能。下面我們通過對該示例進行分析,讓大家熟悉這個輕量級的框架。
1、首先看一下 sample 目錄的結構:
sample
├── Android.mk
├── apps
│ ├── Android.mk
│ ├── client
│ └── upgrade
├── frameworks
│ ├── Android.mk
│ └── PlatformLibrary
├── MODULE_LICENSE_APACHE2
├── procts
│ ├── AndroidProcts.mk
│ └── sample_addon.mk
├── README.txt
├── sdk_addon
│ ├── hardware.ini
│ └── manifest.ini
└── skins
└── WVGAMedDpi
Android.mk: 該文件用於編寫構建規則,默認繼承 Android 的 make 框架。
frameworks: 該目錄在這里的意義等同於 Android 源碼中的 frameworks 。
PlatformLibrary: 該目錄就自定義共享庫。
apps: 該目錄用於編寫依賴該庫的應用程序。經過測試也可以用來編寫不依賴該庫的程序,這有個好處,讓開發商可以把自己特有的應用集成到框架中。
client 與 upgrade: 這是兩個依賴該庫的應用程序示例。
procts: 該目錄中的文件對包含該庫與 Android 框架集成的信息,如模塊名稱等。
AndroidProcts.mk: 指明該模塊的 make 配置文件的在哪裡。
sample_addon.mk :模塊的配置信息。
sdk_addon: 該目錄對該庫的硬體需求進行定義。
hardware.ini: 定義模塊對硬體的需求。
manifest.ini: 模塊的說明文件。名稱、供應商等。
skins: 該目錄用於存放自定義皮膚。
WVGAMedDpi: 已經定義好的一套皮膚。
2.如何封裝 Java 共享庫?
PlatformLibrary 為我們展示了封裝 Java 共享庫的方法。其目錄結構如下: frameworks/PlatformLibrary
├── Android.mk
├── com.example.android.platform_library.xml
├── java
│ └── com
│ └── example
│ └── android
│ └── platform_library
│ └── PlatformLibrary.java
└── README.txt
Android.mk: 該文件說明如何構建該模塊。
com.example.android.platform_library.xml: 該文件是模塊注冊時需要的文件。該文件需要被放置到 /system/etc/permissions 目錄下。
Java /*: Java 源碼所在目錄。具體步驟:
a、編寫 Java 庫,並將源碼放到 java 目錄下。這一步和編寫普通 Java 程序沒有差別。
b、編寫 Android.mk,內容如下:
# 獲得當前目錄,清空環境變數
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) # 源碼所在目錄,all-subdir-java-files 表示所有了目錄中的 Java 文件。
LOCAL_SRC_FILES := \
$(call all-subdir-java-files) # 該模塊是可選的。
LOCAL_MODULE_TAGS := optional # Java 模塊名稱
LOCAL_MODULE:= com.example.android.platform_library # 編譯為 Java 庫。最近以 jar 的形式而不是 apk 的形式存在。
include $(BUILD_JAVA_LIBRARY) # 構建該庫的 API 文檔
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= platform_library
# 文檔對應的庫
LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library
# 庫的類型
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true # 編譯為 Java API。
include $(BUILD_DROIDDOC)
c、編寫 com.example.android.platform_library.xml,內容如下:
< xml version="1.0" encoding="utf-8" >
<permissions>
<!-- 庫的名稱及對應的 Jar 文件位置 -->
<library name="com.example.android.platform_library"
file="/system/framework/com.example.android.platform_library.jar"/>
</permissions> 現在基本的庫我們已經編寫完成,現在需要對框架中的其它文件進行配置。
d、編寫 sample/frameworks/Android.mk, 內容如下:
# 包含子目錄中的所有 make 文件 include $(call all-subdir-makefiles) 該文件與 sample/Android.mk 文件相同。
e、編寫 sample/sdk_addon/manifest.ini,內容如下: # 該模塊的名稱、供應商及描述
name=Sample Add-On
vendor=Android Open Source Project
description=sample add-on # 構建該模塊的 Android 平台代號
api=3 # 模塊的版本號。必須為整數。
revision=1 # 該模塊中包括的共享庫列表
libraries=com.example.android.platform_library # 對每個庫的詳細定義,格式如下:
# <library.name>=<name>.jar;<desc> # <library.name>: 通過前面 libraies 定義的庫的名稱。
# <name>.jar: 包含庫 API 的 jar 文件。該文件放在 libs/add-on 下面。
com.example.android.platform_library=platform_library.jar;Sample optional plaform library 該文件還可包括該模塊的其它定義,如皮膚等,為了保持該文檔清晰易懂的初衷,這里不做介紹,需要了解可以給我郵件。
f、編寫 sample/procts/sample_addom.mk,內容如下:
# 要植入系統鏡像的應用及可選類庫。可以包括 Java 庫和本地庫。這里我們只有 Java 庫。
PRODUCT_PACKAGES := \ com.example.android.platform_library # 把 xml 文件復制到系統鏡像中相應的位置去。
PRODUCT_COPY_FILES := \ vendor/
sample/frameworks/PlatformLibrary/com.example.android.platform_library.xml:system/etc/permissions/
com.example.android.platform_library.xml # 這個擴展的名稱
PRODUCT_SDK_ADDON_NAME := platform_library # 把模塊的 manifest 和硬體配置文件復制到系統鏡像中相應的位置。 PRODUCT_SDK_ADDON_COPY_FILES := \
vendor/sample/sdk_addon/manifest.ini:manifest.ini \
vendor/sample/sdk_addon/hardware.ini:hardware.in # 把庫的 Jar 包復制到相應的位置。 PRODUCT_SDK_ADDON_COPY_MODULES := \
com.example.android.platform_library:libs/platform_library.jar # 文檔的名稱。必須與。
# LOCAL_MODULE:= platform_library
PRODUCT_SDK_ADDON_DOC_MODULE := platform_library # 這個擴展繼承系統擴展。 $(call inherit-proct, $(SRC_TARGET_DIR)/proct/sdk.mk) # 這個擴展的真實名字。這個名字會用於編譯。
# 用 'make PRODUCT-<PRODUCT_NAME>-sdk_addon' 的形式來編譯此擴展。
PRODUCT_NAME := sample_addon
g、編寫 sample/procts/AndroidProcts.mk,內容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/sample_addon.mk h、最後運行make -j8 PRODUCT-sample_addon-sdk_addon,編譯擴展。
至此,我們就完成了 Java 庫的封裝。
3、接下來我們再來看如何通過 JNI 的方式對 C 代碼進行封裝。
a、在 sample/frameworks/PlatformLibrary 目錄下添加一個文件夾,用於放置 JNI 本地代碼,目錄結構如下:
frameworks/PlatformLibrary/jni
├── Android.mk
└── PlatformLibrary.cpp
b、把 frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
文件改寫為 JIN 調用介面,代碼如下 : package com.example.android.platform_library; import android.util.Config;
import android.util.Log; public final class PlatformLibrary {
static { / Load the library. If it's already loaded, this does nothing. System.loadLibrary("platform_library_jni");
private int mJniInt = -1; public PlatformLibrary() {} / Test native methods. public int getInt(boolean bad) {
// this alters mJniInt //
int result = getJniInt(bad); // reverse a string, for no very good reason //
String reverse = reverseString("Android!"); Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'"); return mJniInt; //
/ Simple method, called from native code. private static void yodel(String msg) {
Log.d("PlatformLibrary", "yodel: " + msg); //
/ Trivial native method call. If "bad" is true, this will throw an
/ exception. native private int getJniInt(boolean bad); / Native method that returns a new string that is the reverse of
/ the original. This also calls yodel(). native private static String reverseString(String str);
}
c、在 frameworks/PlatformLibrary/jni/PlatformLibrary.cpp 中編寫 PlatformLibrary.java 中規定本地調用的具體實現。
d、編寫 frameworks/PlatformLibrary/jni/Android.mk,內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional # JNI 模塊的名稱
LOCAL_MODULE:= libplatform_library_jni # 依賴的源代碼文件
LOCAL_SRC_FILES:= \
PlatformLibrary.cpp # 編譯時需要的庫
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils # 沒有靜態庫
LOCAL_STATIC_LIBRARIES := # 包含必須的 JNI 頭文件
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) # 編譯器選項
LOCAL_CFLAGS += # 對該模塊不進行預編譯。使用預編譯可以提高模塊的性能。
LOCAL_PRELINK_MODULE := false # 把它編譯成動態共享庫
include $(BUILD_SHARED_LIBRARY) 該文件主要定義了本地庫的名字、依賴、編譯選項及編譯方式。
e、修改 frameworks/PlatformLibrary/Android.mk,在末尾添加如下兩行:
include $(CLEAR_VARS) # 調用子目錄中的 make 文件。
include $(call all-makefiles-under,$(LOCAL_PATH))
f、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加該 JNI 本地庫。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni
g、編譯即可。至此,添加 JNI 庫完畢。
4、添加接下來我們再看看如何添加原生應用程序
添加原生應用程序就很簡單了,只需要把按照 Android 應用開發的基本方法,寫好一個應用,該應用可以依賴這個擴展,也可以不依賴。如 sample 中的 client 應用,目錄結構如下: apps/client/
├── AndroidManifest.xml
├── Android.mk
└── src
└── com
└── example
└── android
└── platform_library
└── client
└── Client.java
a、在應用根目錄中添加一個 Android.mk 文件,內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := user # 目標名稱
LOCAL_PACKAGE_NAME := PlatformLibraryClient # 只編譯這個apk包中的java文件
LOCAL_SRC_FILES := $(call all-java-files-under, src) # 使用當前版本的 SDK
LOCAL_SDK_VERSION := current # 依賴使用剛才編寫的擴展
LOCAL_JAVA_LIBRARIES := com.example.android.platform_library include $(BUILD_PACKAGE)
b、在 AndroidManifest.xml 中添加一句:
<uses-library android:name="com.example.android.platform_library" />
c、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加該 JNI 本地庫。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni \
PlatformLibraryClient
d、編譯即可。至此,添加 JNI 庫完畢。
5、其他功能如添加皮膚等,這里就不一一示範了,請參考<sdk-src>/vendor/sample。
Ⅶ android系統中查看內存信息
看下大致內存使用早團轎情況 (free+buffers+cached)
proc/meminfo 機器的內存使用信息
/proc/pid/maps pid為進程號,顯示當前進程所佔用的虛擬地址。
/proc/pid/statm 進程所佔用的內存
df 查看 存儲空間使用情況
ps -t |grep system_server (或 surfaceflinger, service manager, media server,zygote) ( 倒數第二個是不是 s) 異常情況有如』D』, 『T』, 『Z』 , 『R』等
mpsys meminfo com.android.mms 列印一個app的mem信息
從以上列印可以看出,一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS
VSS - Virtual Set Size 虛擬耗用內存(包含共享庫佔用的內存)是單個進程全部可訪問的地址空間
RSS - Resident Set Size 實際使用物理內存(包含共享庫佔用的內存)是單個進程實際佔用的內存大小,對於單個共享庫, 盡管無論多少個進程使用,實際該共享庫只會被裝入內存一次。
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存)
USS - Unique Set Size 進程獨自佔用的物理內存(不包含共享庫佔用的內存)
USS 是或態針對某個進程開始有可疑內存泄露的情況,進行檢測陸肆的最佳數字。懷疑某個程序有內存泄露可以查看這個值是否一直有增加
使用mpsys meminfo查看內存信息
腳本:
adb shell ps -t> tsq/ps.txt
adb shell top -t -m 5 -n 2 > tsq/top.txt
adb shell service list > tsq/serviceList.txt
adb shell cat /proc/meminfo >tsq/meminfo
adb shell cat /proc/buddyinfo >tsq/buddyinfo
adb shell procrank > tsq/procrank.txt
adb shell cat proc/sched_debug >tsq/sched_debug.txt
adb shell cat proc/interrupts >tsq/interrupts.txt
adb shell mpstate > tsq/mpstate.txt
adb shell bugreport > tsq/bugreport.txt
@echo "finish."
pause
可以按以下步驟進行:
Android應用的資料庫一般都是私有的,其他應用無法訪問,那麼怎麼在手機已root的前提下,在自己的應用中讀取指定應用中的數據信息呢,現提供一種思路。
以uc瀏覽器歷史瀏覽記錄為例:
一:對手機進行root。
某些廠家的Android設備是支持在系統設置中一鍵root的,如魅族手機。更通用的情況下一般是用第三方軟體進行root,如KingRoot。
二:在手機上安裝RootExplorer。
RootExplorer是在Android上使用很方便的文件瀏覽器,借用它,我們可以找到uc瀏覽器的歷史記錄資料庫所在為data/data/com.UCMobile/databases/history/history。
三:將資料庫文件復制到sd卡指定目錄。
四:從sd卡資料庫文件中讀取數據。
五:將數據載入到Recyclerview中展示。
至此,我們已經實現了在自己應用中讀取其他應用資料庫數據的一個完整過程,誠然這種方式存在許多局限性,但不失為解決方案的一種。
Ⅸ Android中靜態庫和共享庫的區別
簡單來講:
靜態庫是在連接階段直接拷貝到代碼中使用的,而共享庫是由載入器載入到內存,在運行時使用的。
編譯出來的靜態庫(這里指jar包)里每個java文件對應的class文件都單獨存在,可以直接導入Eclipse等IDE使用
而編譯出來的共享庫(jar包),內部是Android位元組碼Dex格式的文件,一般無法導入Eclipse等IDE使用。Android.mk中由BUILD_JAVA_LIBRARY指定生成共享BUILD_STATIC_JAVA_LIBRARY指定生成靜態庫。
Ⅹ Android圖形系統系統篇之HWC
HWC (hwcomposer)是Android中進行窗口( Layer )合成和顯示的HAL層模塊,其實現是特定於設備的,而且通常由顯示設備製造商 (OEM)完成,為 SurfaceFlinger 服務提供硬體支持。
SurfaceFlinger 可以使用 OpenGL ES 合成 Layer ,這需要佔用並消耗GPU資源。大多數GPU都沒有針對圖層合成進行優化,當 SurfaceFlinger 通過GPU合成圖層時,應用程序無法使用GPU進行自己的渲染。而 HWC 通過硬體設備進行圖層合成,可以減輕GPU的合成壓力。
顯示設備的能力千差萬別,很難直接用API表示硬體設備支持合成的 Layer 數量, Layer 是否可以進行旋轉和混合模式操作,以及對圖層定位和硬體合成的限制等。因此HWC描述上述信息的流程是這樣的:
雖然每個顯示設備的能力不同,但是官方要求每個 HWC 硬體模塊都應該支持以下能力:
但是並非所有情況下 HWC 都比GPU更高效,例如:當屏幕上沒有任何變化時,尤其是疊加層有透明像素並且需要進行圖層透明像素混合時。在這種情況下, HWC 可以要求部分或者全部疊加層都進行GPU合成,然後 HWC 持有合成的結果Buffer,如果 SurfaceFlinger 要求合成相同的疊加圖層列表, HWC 可以直接顯示之前合成的結果Buffer,這有助於提高待機設備的電池壽命。
HWC 也提供了 VSync 事件,用於管理渲染和圖層合成時機,後續文章會進行介紹。
Android7.0提供了HWC和HWC2兩個版本,默認使用HWC,但是手機廠商也可以選擇HWC2,如下所示:
SurfaceFlinger 通過 HWComposer 使用 HWC 硬體能力, HWComposer 構造函數通過 loadHwcMole 方法載入HWC模塊,並封裝成 HWC2::Device 結構,如下所示:
上述通過 hw_get_mole 方法(hardware\libhardware\hardware.c)載入 hwcomposer 模塊,此模塊由硬體廠商提供實現,例如:hardware\libhardware\moles\hwcomposer\hwcomposer.cpp是 hwcomposer 模塊基於HWC1的default實現,對應的共享庫是 hwcomposer.default.so ;hardware\qcom\display\msm8994\libhwcomposer\hwc.cpp是高通MSM8994基於HWC1的實現,對應的共享庫是 hwcomposer.msm8994.so 。
如果是基於HWC2協議實現,則需要實現hwcomposer2.h中定義的 hwc2_device_t 介面,例如: class VendorComposer : public hwc2_device_t 。Android7.0的 hwcomposer 模塊默認都是基於HWC1協議實現的。
每個HAL層模塊實現都要定義一個 HAL_MODULE_INFO_SYM 數據結構,並且該結構的第一個欄位必須是 hw_mole_t ,下面是高通MSM8994 hwcomposer 模塊的定義:
frameworks\native\services\surfaceflinger\DisplayHardware\HWC2.h主要定義了以下三個結構體:
它們是對 HWC 硬體模塊的進一步封裝,方便進行調用。 HWC2::Device 持有一個 hwc2_device_t ,用於連接硬體設備,它包含了很多HWC2_PFN開頭的函數指針變數,這些函數指針定義在 hwcomposer2.h 。
在 HWC2::Device 的構造函數中,會通過 Device::loadFunctionPointers -> loadFunctionPointer(FunctionDescriptor desc, PFN& outPFN) -> hwc2_device_t::getFunction 的調用鏈從硬體設備中獲取具體的函數指針實現。關鍵模板函數如下所示:
這些函數指針主要分為三類:
通過上述函數指針可以與 hwc2_device_t 表示的硬體合成模塊進行交互。三類指針分別選取了一個示例:
可以通過類圖,直觀感受下引用關系。
HWC2::Device 構造函數除了完成獲取函數指針實現以外,還會通過 Device::registerCallbacks 向硬體設備注冊三個 Display 的回調:熱插拔,刷新和VSync信號,如下所示:
總結一下, HWC2::Device 構造函數向硬體設備注冊三個 Display 回調:熱插拔,刷新和VSync信號。當 HWC2::Device 收到這些回調時,會通過監聽器向外回調到對應的HWComposer函數: HWComposer::hotplug / HWComposer::invalidate / HWComposer::vsync 。HWComposer再通過這些信息驅動對應工作,後續文章進行介紹。
上文提到 HWC2::Device 中的函數指針是hardware\libhardware\include\hardware\hwcomposer2.h中定義的,除此之外,該頭文件還定義了一些重要的結構體,這里介紹兩個比較重要的:
DisplayType 表示顯示屏類型,上面注釋已經介紹,重點看下Layer合成類型:
那麼一個 Layer 的合成方式是怎麼確定的那?大致流程如下所示:
本篇文章只是簡單介紹了HWC模塊的相關類: HWComposer 、 HWC2::Device 、 HWC2::Display 和 HWC2::Layer ,以及它們的關系。此外,還著重介紹了Layer的合成方式和合成流程。後續文章會更加全面的介紹 SurfaceFlinger 是如何通過HWC模塊完成Layer合成和上屏的(虛擬屏幕是到離屏緩沖區)。