1. 程式人生 > >將自定義的jar包新增到framework層(錯誤)

將自定義的jar包新增到framework層(錯誤)

原java類檔案放到framework下面,通過原始碼編譯生成系統jar包:

專案中,客戶要求將jar新增到framework裡,以便所有的apk都可以呼叫這個jar。網上查看了一些資料,各有不同,下面是我自己總結各方資料來解決問題,僅供參考:

1.首先,在framework/base/下面建一個資料夾,名字可以隨便取,但語義最好能夠和jar相關,看了一目瞭然。(這裡我定義一個資料夾:test)

2.在新建的資料夾(這裡用test代替)裡新建一個java資料夾,一個mk檔案;mk、檔案要自己寫這裡給個sample:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE:= 你定義的模組名字或者說jar包名字 比如:self.test.support
include $(BUILD_JAVA_LIBRARY)

3.在java資料夾中,新增目錄結構及jar包名稱空間的結構:如com.test.support.那麼就要在java資料夾下新增com資料夾,然後在com資料夾下新增test資料夾,以此類推;新增完目錄結構後,就將要新增的jar的java類檔案放到最後一個資料夾中,對java命令編譯的人一看就知道什麼意思了。

在frameworks\base下新建xxx目錄,下面的目錄結構如下,必須要有一個java的目錄:
│  Android.mk
└─java
    └─com
        └─android
            └─frameworkunit
                    FrameworkTest.java

4.在android/build/target/product目錄下的generic_no_telephony.mk檔案中PRODUCT_PACKAGES := \後面追加你定義的模組名字如“ self.test.support \“,不然android整體編譯時不會自動去編譯你定義的那個模組的。

5. 在android/build/target/product目錄下的base.mk檔案中PRODUCT_PACKAGES += \後面也同樣追加你定義的模組名字如“ self.test.support \“;

在android/build/core目錄下的pathmap.mk中的FRAMEWORKS_BASE_SUBDIRS := \後面追加你在base目錄下新增的那個資料夾名 (見步驟一 如:test \)

最後 make clean
//這步可以不執行,不然整個系統都要重新編 時間太長

 make update-api //這步要執行 
 make 或者在frameworks\base\xxx下執行mm 生成jar包

參考:

1:http://blog.csdn.net/tkwdmylove/article/details/39289079

2:http://blog.chinaunix.net/uid-22816738-id-4358584.html

--------------------分割線-----------------------------------------

生成jar包後,參考:http://blog.csdn.net/jack_liu_2008/article/details/49764131 將jar新增進framework.jar,使得framework.jar能呼叫自己jar包裡的方法

1.在原始碼frameworks/opt/中建立資料夾demo, 將第三方的demo.jar拷貝拷貝到該目錄下,同時在該目錄下建立Android.mk (參考android2.1)

注意:demo.jar說的是打包格式為.dex,不是.class格式的

Andorid.mk寫入:

LOCAL_PATH:= $(my-dir)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := myjar:demo.jar
include $(BUILD_MULTI_PREBUILT)

-----------分割線---------------------

“myjar” 只是一個標示名,可以用任意命名替換,該名稱在下面步驟中會用到

2 將demo.jar編譯到原始碼環境中
執行命令:mmm framework/opt/demo/
編譯之後會生成
out/target/product/xxx/obj/JAVA_LIBRARIES/demo_intermediates/javalib.jar

3 在framework加入demo.jar,需要修改framework/base/Android.mk:

# Build ext.jar
# ============================================================

# NOTICE notes for non-obvious sections
# apache-http - covered by the Apache Commons section.


ext_dirs := \
    ../../external/nist-sip/java \
    ../../external/apache-http/src \
    ../../external/tagsoup/src \
    ../../external/libphonenumber/java/src

ext_src_files := $(call all-java-files-under,$(ext_dirs))

ext_res_dirs := \
    ../../external/libphonenumber/java/src

# ==== the library =========================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(ext_src_files)

LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core
LOCAL_JAVA_RESOURCE_DIRS := $(ext_res_dirs)
LOCAL_STATIC_JAVA_LIBRARIES := myjar 增加該行,myjar是步驟1中的標示名
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := ext

LOCAL_DX_FLAGS := --core-library

include $(BUILD_JAVA_LIBRARY)

---------------分割線-----------------------------


4 將demo.jar編譯到framework中
執行命令: mmm framework/base/
會更新3個系統jar包
out/target/product/xxx/system/framework/ext.jar
out/target/product/xxx/system/framework/framework.jar
out/target/product/xxx/system/framework/framework2.jar

需要注意:
編譯的中間檔案會存在下列目錄中
out/target/common/obj/JAVA_LIBRARIES/demo_intermediates/
out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/xxx
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/xxx
out/target/common/obj/JAVA_LIBRARIES/framework2_intermediates/xxx
out/target/product/xxx/obj/JAVA_LIBRARIES/demo_intermediates/javalib.jar
out/target/product/xxx/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar
out/target/product/xxx/obj/JAVA_LIBRARIES/framework_intermediates/javalib.jar
out/target/product/xxx/obj/JAVA_LIBRARIES/framework2_intermediates/javalib.jar
如果除錯中不想打包第三方的Jar包時,需要手動刪除上述目錄/檔案,再重新編譯。

經過上述步驟,就可以在framework呼叫demo.jar包中函數了。

--------------------------

後面發現阻止了其他程式安卓,以及jar包裡有AIDL的話,如果原始碼裡有專案也引用了framework.jar,則會因為包名類名相同導致出現混淆錯誤。