Câu hỏi Làm thế nào để xây dựng Android SDK với các API ẩn và nội bộ có sẵn?


Tôi muốn xây dựng lại Android SDK (hoặc thay vì chỉ android.jar) để bao gồm các API nội bộ và ẩn.

Tôi không thể tìm thấy bất kỳ tài liệu hoặc thảo luận nào về cách thực hiện việc này. Tôi có một môi trường xây dựng Ubuntu CyanogenMod đã được thiết lập có thể xây dựng cm7.

Bây giờ, tôi đọc mà làm cho SDK sẽ xây dựng SDK nhưng tôi muốn xây dựng một SDK bao gồm các phương thức và các trường được đánh dấu là ẩn bằng cách sử dụng @hide. Điều này có thể không?

Những gì tôi muốn làm là thay đổi một ứng dụng sử dụng API ẩn và để xây dựng lại nó, tôi muốn sử dụng SDK đã sửa đổi.


76
2017-10-25 10:55


gốc


@ Ẩn chỉ ẩn javadoc, tất cả các phương pháp này vẫn có sẵn - Blundell
@hide loại bỏ chúng khỏi các tệp lớp. - Thomas Hofmann
Đã liên kết: stackoverflow.com/questions/4951146/… - Blundell
Tôi biết rằng tôi có thể sử dụng sự phản chiếu nhưng tôi muốn thay đổi một ứng dụng hiện có sử dụng API ẩn mà không cần refelction và tôi không muốn thay đổi tất cả các mã exsiting để sử dụng refelction. - Thomas Hofmann
Tôi nghĩ bạn có thể xóa @Hidden nhãn của API bạn muốn truy cập, sau đó thực thi make update-api và make SDK để tạo SDK của riêng bạn. - dreamtale


Các câu trả lời:


Đây là những gì tôi luôn luôn làm để sử dụng api ẩn.

  1. Xây dựng repo hoặc download jars từ https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
  2. sao chép ra / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar (tốt hơn để đổi tên nó thành một cái gì đó như framework_all.jar)
  3. cấu hình đường dẫn xây dựng dự án của bạn -> thư viện -> thêm các jars bên ngoài này. Trong Đặt hàng và Xuất, hãy di chuyển lên và trước android.jar

61
2017-11-15 16:10



Đây là cách đơn giản nhất đối với tôi, cảm ơn! - JoonasS
Điều này làm việc cho tôi quá! bây giờ tôi có thể tiếp tục với nhiệm vụ thực tế, cảm ơn vì điều này - CurlyPaul
IMHO, Đây là cách dễ nhất và nhanh nhất. - Patrick Cho
Không có cách nào để đánh dấu đây là câu trả lời đúng không? - Koying
phương pháp này có hoạt động với tất cả các thiết bị không, hoặc nó chỉ hoạt động với thiết bị được nhắm mục tiêu? - Hải Phong


Tôi đã làm một số điều tra về điều này, và kết luận của tôi chỉ đơn giản là: Điều này không thể được thực hiện mà không có khá nhiều công việc. Đọc phần còn lại của câu trả lời này để biết chi tiết về những gì tôi đã tìm thấy.


android.jar thực sự bao gồm "api công khai" của framework.jar và core.jar được tìm thấy trong system/frameworks/ trên thiết bị. android.jar là một loại mà tôi gọi là tiêu đề thư viện Java, tất cả việc triển khai thực hiện trong mã byte thực tế chỉ là throw new RuntimeException("stub");, điều này cho phép bạn xây dựng dựa vào android.jar (ví dụ: trong Eclipse), nhưng việc thực hiện phải được thực hiện trên một thiết bị hoặc trình giả lập.

API công khai của SDK Android được xác định bởi các lớp / phương thức / trường không phải bắt đầu bằng @{hide} chú thích javadoc. I E. mọi thứ không phải chú thích được bao gồm trong SDK.

android.jar được xây dựng từ các nguồn nằm ở out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates mà chính nó được tạo ra bởi công cụ DroidDoc nằm ở build/tools/droiddoc.

DroidDoc là công cụ (có thể được điều chỉnh từ javadoc hoặc sử dụng javadoc) để tạo tài liệu Android SDK thực tế. Như là một tác dụng phụ, và có lẽ bởi vì nó đã phân tích tất cả các javadoc, nó cũng spews ra stub android mà sau đó được biên dịch vào android.jar được phân phối trong SDK.

Vì vậy, để bao gồm nội dung bị ẩn, bạn có thể, nếu bạn chỉ muốn bao gồm các phần cụ thể, chỉ cần xóa @hide chú thích và xây dựng lại SDK.

Tuy nhiên nếu bạn muốn bao gồm tất cả các phần ẩn, mọi thứ trở nên phức tạp hơn rất nhiều. Bạn có thể sửa đổi DroidDoc (nguồn có liên quan nằm trong build/tools/droiddoc/src/Stubs.java) như vậy không có gì được phát hiện là ẩn. Điều này là khá tầm thường và tôi đã thử điều này, tuy nhiên các cuống mà sau đó được tạo ra không biên dịch chút nào.

Kết luận của tôi bây giờ là điều này đơn giản là không khả thi. Sơ khai được tạo ra nếu bạn loại bỏ một phần của DroidDoc phát hiện chú thích ẩn, chỉ đơn giản là không compilable, và sẽ đòi hỏi khá nhiều công việc để biên dịch một cách chính xác.

Vì vậy, câu trả lời của tôi cho câu hỏi của bạn là: Không, điều này không thể được thực hiện, mà không làm rất nhiều công việc. Lấy làm tiếc.


Một lưu ý phụ về mkstubs dụng cụ. mkstubs được sử dụng khi bạn tạo SDK addon, nghĩa là các addons bạn có thể tìm thấy trong trình quản lý SDK Android từ các nhà cung cấp, ví dụ: Samsung cung cấp cho bạn một API bổ sung cho các nội dung cụ thể cho điện thoại Samsung. mkstubs không giống như quá trình tạo ra DroidDoc, tuy nhiên nó không sử dụng @hide chú thích, nó sử dụng .defs tệp mô tả gói / lớp / trường nào cần bao gồm hoặc loại trừ khỏi addon SDK của bạn.

Tuy nhiên, điều này không liên quan đến câu hỏi, vì bản dựng SDK Android không phải sử dụng mkstubs dụng cụ. (Không may.)


39
2018-03-05 10:23



Tôi cũng có một cái nhìn. Bên cạnh Droiddoc còn có một công cụ gọi là mkstubs trong / development / tools / mkstubs. Nó được gọi trong khi xây dựng và theo như tôi đã thấy nó sẽ sửa đổi các tập tin lớp học stubbing thứ ra khỏi chúng. Trong build / core / tasks / sdk-addon.mk có đoạn mã sau: define stub-addon-jar $ (gọi stub-addon-jar-file, $ (1)): $ (1) | mkstubs $ (thông tin Stubbing addon jar sử dụng $ (PRODUCT_SDK_ADDON_STUB_DEFS)) $ (ẩn) java -jar $ (gọi module-installed-files, mkstubs) $ (nếu $ (ẩn) ,, - v) \ "$$ <" "$$ @" @ $ (PRODUCT_SDK_ADDON_STUB_DEFS) endef - Thomas Hofmann
Thật không may, tôi không phải vào công cụ này nhưng quá tôi có vẻ như tất cả phụ thuộc vào một biến gọi là ẩn. Tôi không tìm thấy nó được thiết lập mặc dù. Nếu bạn tìm kiếm $ (ẩn) trong các tệp xây dựng khác, bạn sẽ thấy rằng rất nhiều phụ thuộc vào giá trị này. Nó dường như cũng ảnh hưởng đến cách C libs được xây dựng. - Thomas Hofmann
@ThomasHofmann: Ban đầu tôi cũng bị nhầm lẫn bởi công cụ mkstubs. Những gì tôi đã học được rằng mkstubs chỉ được sử dụng khi bạn đang xây dựng một (nhà cung cấp) sdk addon, không phải khi bạn chỉ cần xây dựng sdk bình thường. Tuy nhiên, mkstubs có nhiều giống như DroidDoc, ngoại trừ nó không sử dụng @hide chú thích, nó "chỉ" sử dụng một .defs tập tin mô tả các gói / lớp / trường nào được đưa vào API của chương trình bổ trợ. - Bjarke Freund-Hansen
@ThomasHofmann: Giới thiệu $(hide), bạn đang bối rối. $(hide) chỉ đơn giản là một tiền tố trong makefiles để ẩn dòng lệnh thực tế của chương trình đang được thực hiện, không có gì hơn, và nó được sử dụng chỉ ở khắp mọi nơi ở khắp mọi nơi. Nó không có gì để làm với SDK Android hoặc @hide chú thích trong mã nguồn. - Bjarke Freund-Hansen


Chúng tôi có thể tái tạo các tệp * .jar từ nền tảng Android.

Đầu tiên, kết nối ADB với thiết bị của bạn. Sau đó chạy:

adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .

Các core.jar chứa các thư viện Java chuẩn (java.*) và framework.jar chứa các thư viện Android (android.*). Điều này là không thể sử dụng được nêu ra, như các tập tin thực tế có định dạng DEX, không phải định dạng JAR.

Chúng tôi có thể chuyển đổi các tệp * .jars được định dạng DEX này thành các JAR thực bằng các công cụ như dex2jar:

dex2jar core.jar
dex2jar framework.jar

Sau đó kéo các lọ này bằng cách sử dụng "Thêm các JAR bên ngoài ..." (giả sử bạn đang sử dụng ADT của Eclipse)

  • nhấp chuột phải vào Project → Properties → Java Build Path → Libraries → Add External JARs... → (Chọn core-dex2jar.jar và framework-dex2jar.jar từ phía trên).

Điều này sẽ cho phép bạn sử dụng các API Java 7 nội bộ và một số. (APK được tạo, theo như tôi thấy, không chứa bất kỳ mã thực nào từ các JAR.)


28
2017-11-25 10:09



Cảm ơn bạn rất nhiều, tôi đã thử rất nhiều cách chỉ có phương pháp của bạn làm việc cho tôi. - SalutonMondo
Điều quan trọng cần lưu ý là phương pháp này vẫn hoạt động với ICS và các hệ thống sau này, nhưng đòi hỏi phải có thêm một số sự tung hứng. Các tệp có liên quan là /system/framework/core.odex, /system/framework/framework.odexvà có thể nhiều hơn nữa. Đây có thể được deodexed (java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core) và reodexed (java -jar smali-2.0.3.jar -x -o core.dex core), và chỉ sau đó dex2jar core.dexthực hiện công việc của mình. - Alex Cohn
không thể tìm thấy core.jar trong marshmallow - mehmet6parmak


Đối với Lollipop dòng chảy có chút khác biệt:

  1. Nhận /system/framework/arm/boot.oat từ thiết bị lollipop

  2. Sử dụng 'java -jar oat2dex.jar boot boot.oat '

  3. Bạn sẽ có 2 thư mục: dex và odex. Đi tới dex và tạo 'java -jar dex2jar.jar framework.dex '
  4. Đổi tên kết quả là framework.jar thành .zip, trích xuất và tìm các lớp bạn cần
  5. Truy cập [sdk_path] / platforms / [target_platform] và trích xuất android.jar (trước tiên hãy đổi tên thành zip).
  6. Sao chép các tệp từ khung được trích xuất đến android.jar được trích xuất. Sau đó nén để nén và đổi tên thành .jar :)

ps: có lẽ bạn cần lặp lại các bước 4-6 cho 'framework_classes2.dex'


16
2018-02-22 08:08



Đối với bước 3, tôi không thể tìm thấy dex2jar.jar tại liên kết đó .... Tôi đã thử rất nhiều thứ và tôi không thể tìm ra. Có một liên kết đến một nơi nào đó? Nó nằm trong SDK Android của tôi không? Tôi không thể tìm thấy nó. - Dwebtron
liên kết là ok. - deviant
xem phần 'phát hành' - deviant
Vì vậy, có vẻ như các phiên bản gần đây của dex2jar đã thay đổi định dạng của tải xuống. Chỉ cần giải nén tải xuống và thay vì 'java -jar ...' chỉ cần chạy tập lệnh 'd2j-dex2jar.sh' hoặc 'd2j-dex2jar.bat', tùy thuộc vào nền tảng của bạn, trực tiếp trên tệp framework.dex - CalumMcCall
tôi đã sao chép cả hai tệp jar vào android.jar, giờ đây studio android cho tôi biết Lỗi: Thực thi không thành công cho công việc ': app: processDebugResources'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Xử lý 'lệnh' D: \ Program \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe ' 'kết thúc với giá trị thoát khác 0 - wutzebaer


DroidCon 2011

Ở đây Erik Hellman từ Sony Ericson giải thích cách truy cập vào các API Android bị ẩn:

http://vimeo.com/30180393 (Liên kết Hmm dường như không hoạt động).

Goto the Trang web DroidCon Ngày 2 cuộn xuống Sử dụng các API ẩn 10:15 và bạn có thể xem nó ở đó.

Liên kết đang chết!

Tôi đã tìm thấy cái này: http://skillsmatter.com/podcast/os-mobile-server/hidden-api dunno sẽ mất bao lâu

Các API chính thức trong SDK Android thường đủ cho hầu hết các ứng dụng thông thường. Tuy nhiên, đôi khi các tình huống mà nhà phát triển cần truy cập vào các dịch vụ hệ thống nội bộ, API và tài nguyên không được xuất bản trong API chính thức. May mắn thay, các API này vẫn có sẵn thông qua một số thủ thuật thông minh và thường có thể hữu ích khi phát triển giải pháp mới và sáng tạo trên Android. Trong phiên này, bạn sẽ tìm hiểu cách truy cập và sử dụng các API được bảo vệ và ẩn này, những hạn chế trong cách sử dụng của chúng và một số mẹo không phải về cách sử dụng chúng một cách an toàn và kiểm soát trên nhiều thiết bị của nhà cung cấp và phiên bản Android. Khán giả sẽ thấy một số bản trình diễn nâng cao mà bạn thường không thể làm với Android. Mong đợi một phiên khá cao cấp với rất nhiều thông tin chi tiết trong nội bộ của nền tảng Android.


15
2017-10-25 11:37



Thật thú vị nhưng tiếc là nó không trả lời câu hỏi của tôi. Tôi đã yêu cầu một cách để thực sự xây dựng lại SDK với các công cụ ẩn bao gồm. - Thomas Hofmann
Có vẻ như tôi đã tìm ra một cách khác để đạt được những gì tôi muốn. Tôi sẽ mô tả nó vào ngày mai. - Thomas Hofmann
Tôi phát hiện ra rằng nếu bạn muốn biên dịch mã nguồn của một dự án sử dụng API ẩn trong ADT, bạn có thể thực hiện các thao tác sau: 1) Tạo một dự án Android cho nguồn. 2) Loại bỏ vùng chứa classpath Android khỏi đường dẫn xây dựng 3) Xác định thư viện người dùng (cũng kiểm tra hộp kiểm thư viện hệ thống) bao gồm các tệp JAR từ bản dựng ASOP ROM, ví dụ: cm7). Các tệp JAR nào bạn sử dụng tùy thuộc vào những gì bạn cần tham khảo. framework-immediates có lẽ sẽ là một phần của nó. - Thomas Hofmann
4) Khi dự án được xây dựng, các lớp thư viện người dùng sẽ không được bao gồm trong APK đang được tạo. API ẩn hiển thị và mọi thứ sẽ biên dịch tốt. - Thomas Hofmann
@Blundell: Bạn có thể vui lòng cập nhật các liên kết .. họ đã chết! - zombie


Hãy thử nhìn vào điều này:

Mục tiêu cuối cùng của các bài viết này là cung cấp cho nhà phát triển sức mạnh của API nội bộ và ẩn mà không cần sử dụng sự phản chiếu. Nếu bạn hoàn thành tất cả các bước được mô tả trong một số phần tiếp theo, bạn sẽ có thể sử dụng Nội bộ và Ẩn API như thể chúng là các API mở công khai. Sẽ không cần phản ánh.

Nhưng nếu bạn đang sử dụng các API không công khai này thì bạn nên lưu ý rằng ứng dụng của bạn có nguy cơ cao. Về cơ bản, không có gì đảm bảo rằng các API sẽ không bị hỏng với bản cập nhật tiếp theo cho hệ điều hành Android. Thậm chí không có đảm bảo về hành vi nhất quán trên các thiết bị từ các nhà cung cấp khác nhau. Bạn hoàn toàn tự làm.

Có ba tình huống bạn có thể muốn làm theo:

  1. Bật cả hai nội bộ và ẩn API (kịch bản A)
  2. Chỉ cho phép ẩn API (kịch bản B)
  3. Chỉ cho phép nội bộ API (kịch bản C)

Kịch bản A là tổng của B và C. Kịch bản B là cách dễ nhất (không yêu cầu sửa đổi bổ sung plugin ADT eclipse).

Kịch bản A: đọc các bộ phận 1, 2, 3, 4, 5

Kịch bản B: đọc các bộ phận 1, 2, 3, 5

Kịch bản C: đọc các bộ phận 1, 2, 3, 4, 5


12
2017-11-10 18:18



Tôi đã đọc mục blog đó. Nó đề cập đến điều này: "1) Android là một dự án nguồn mở. Chúng tôi có thể tải xuống mã nguồn và tùy chỉnh hệ thống xây dựng để nó không loại trừ các lớp nội bộ và ẩn khỏi android.jar. Đây là một cách khó khăn". Thật không may, nó không đi vào chi tiết. - Thomas Hofmann
Chuyển đến phần cuối của bài đăng trên blog (devmaze.wordpress.com/2011/01/19/…), có một liên kết (github.com/inazaruk/android-sdk/tree/master/platforms) cho các API Android được tạo sẵn với tất cả các API nội bộ và ẩn. - Bob
Các liên kết đã cho không thể truy cập, yêu cầu sự cho phép của tác giả - SHAHS


Bạn có thể tải xuống bản sửa đổi android.jar được sử dụng làm API ẩn từ kho lưu trữ này. Làm theo hướng dẫn ở đó.


5
2017-09-17 08:50



Câu trả lời này nên được upvoted nhiều hơn vì nó là giải pháp đơn giản nhất. Mọi người, nếu bạn đang tìm kiếm một giải pháp - biết rằng những người khác đã làm điều đó và đặt một giải pháp cho repo github đó. Sử dụng nó và tận hưởng! )) - Mixaz


Tôi đã từng viết một số kịch bản Groovy để trích xuất các tệp java từ một thanh toán repo từ http://source.android.com/ và sau đó biên dịch chúng mà không cần một chuỗi công cụ đầy đủ để biên dịch tất cả các nguồn Android, bao gồm các bước cần thiết khác (bao gói, tạo tài nguyên, v.v.).

Họ có thể được tìm thấy ở đây:

https://github.com/thoutbeckers/CollectAndroid

Nhưng chắc chắn điều này sẽ cần cập nhật cho bất cứ điều gì sau khi Gingerbread, chủ yếu là bằng cách thiết lập các thư mục chính xác trong "rootdirs" trong tập tin cấu hình (CollectConfig.groovy).

Vào thời điểm đó tôi thường xuyên sử dụng điều này để phát triển với tất cả các API ẩn và các nguồn (cũng có vấn đề tại thời điểm đó) có sẵn.

Như đã đề cập ở nơi khác com / android / internal / ** sẽ vẫn bị ẩn trong các phiên bản ADT gần đây do quy tắc truy cập được áp dụng.


1
2017-09-18 11:29





Đây là một bài đăng blog trên trang web của Sony Ericsson với Erik Hellmans nói chuyện và mã và một số tài liệu tham khảo mà tôi nghĩ rằng sẽ hữu ích cho bạn.

Trân trọng
  / Johan


0
2017-11-17 13:40





Tôi không thể bình luận nhưng đây là cơ bản một bình luận cho @ KennyTM's (https://stackoverflow.com/a/13550030/2923406) câu trả lời xuất sắc:

Nếu bạn thấy mình có lỗi sau trong Eclipse:

The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class   files

(Tức là, android.internal. * không khả dụng)

Sau đó, một giải pháp khả thi là áp dụng cùng một phương thức cho /system/framework/framework2.jar. Sử dụng Trình giả lập Android cho SDK19 Tôi có thêm cái bình này. Trên HTC One của tôi thậm chí còn có một framework3.jar.


0
2018-06-19 14:16





Câu trả lời của Long đã làm việc cho tôi, nhưng tôi vẫn còn thiếu một số lớp tôi cần, cụ thể là android.provider.Telephony. Tôi đã có thể thêm nó như thế này:

  1. Tìm lớp học ở đâu

    $ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
    $ find . | grep "/Telephony.class"
    ./telephony-common_intermediates/classes/android/provider/Telephony.class
    ./android_stubs_current_intermediates/classes/android/provider/Telephony.class
    
  2. Thêm các lớp mới và xây dựng lại tệp khung JAR

    cd /path/to/temp/folder
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
    cd classes
    jar cvf ../framework.jar .
    

Hoặc bạn chỉ có thể lười biếng và bao gồm tất cả các lớp vào một tệp jar khổng lồ:

cd /path/to/temp/folder
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .

0
2017-11-03 19:55