天天看點

Android中aidl如何import檔案

如果你做Android開發,那就應該會知道aidl工具的,但是會使用aidl指令行工具的人有嗎有嗎有嗎,如果有的話你們為神馬不出來寫寫怎麼用!!!!

用aidl指令行的如果不出意外肯定會遇見類似這樣的錯誤

$ aidl IRemoteServiceCallback.aidl 
IRemoteServiceCallback.aidl:19: couldn'
t find import for class android.location.Location

      

遇到錯誤,自然要先看下aidl的幫助是怎麼寫的

$ aidl
usage: aidl OPTIONS INPUT [OUTPUT]
       aidl --preprocess OUTPUT INPUT...

OPTIONS:
   -I<
DIR>
    search path for
 import statements.
   -d<
FILE>
   generate dependency file.
   -p<
FILE>
   file created by --preprocess to import.
   -o<
FOLDER>
 base output folder for
 generated files.
   -b         fail when trying to compile a parcelable.
      

看到如此簡潔不明了的介紹你有何感想?

多寫一句會死啊!!!我讨厭這種假人,以為開發Android的人了解能力都很強嗎,不僅help此般不負責任,tutorial也是如此,隻有一句

Add the .aidl file to your makefile - (the ADT Plugin for Eclipse manages this for you). Android includes the compiler, called AIDL, in the tools/ directory.

其實這個介紹更廢物,它不告訴你是哪個tools,我想當然的以為是sdk下的tools檔案夾,怎麼都找不到aidl的所在

難道所有的人都在用Eclipse開發Android嗎,我去google了一下,問這個問題的大有人在,Google為什麼也不修正一下文檔。

google在批判apple時說

如果 Google 不行動起來,那我們都将面臨一個殘酷的未來:一個人、一家公司、一款裝置、一個營運商将是我們唯一的選擇。

而現在google做的呢,它雖然沒有強迫我們隻用Eclipse,但它實際上就是這麼做的,如同Adobe非強制的要求你用Flash來開發ActionScript一樣

牢騷完了,讓我們來一步步解決這個豬血問題

當文檔不能幫你的時候,看Android代碼吧。如何擷取代碼,Google的文檔寫的很清楚,其實Google大部分的文檔都還是夠明了的TAT

以下

ANDROID

代表android代碼樹的根

ANDROID/frameworks/base/tools/aidl

裡是aidl工具的C++代碼,我沒從中獲得有用資訊。或許很可能是我對C++代碼不太有感。。。

一炮打不響就換一個洞,既然Eclipse可以處理aidl檔案,我就來上Eclipse的Android插件ADT吧。aidl相關的檔案是這個

ANDROID/sdk/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
      

你問我如何找到的嗎?Linux上的經典工具要經常用才能算是經典

$ grep -ri aidl Android/android-source/sdk/eclipse/plugins/com.android.ide.eclipse.adt/
      

880行有一個

private boolean handleAidl

函數,看名字就是這地方了。一路摸下去,直到890行

command[index++
] = "
-p"

 +
 Sdk
.getCurrent().getTarget(getProject()).getPath( //
$NON-NLS-1$

                IAndroidTarget
.ANDROID_AIDL
);
      

看到嗎,在這兒發現了-p參數,但還不知道它是什麼,順着此條代碼追蹤,我們找到了這樣一個檔案

ANDROID/sdk/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
      

現在找到30行,我們終于知道,原來這個-p所指的

file created by --preprocess to import

就是一個名叫

framework.aidl

的檔案

/**
 OS Path to the "framework.aidl" file. */


    public
 final
 static
 int
 ANDROID_AIDL
        = 2
;
      

哈哈,讓我來驗一驗你的真身!!!

$ find Android/android-sdk-linux_86/ -name framework.aidl
Android/android-sdk-linux_86/platforms/android-3/framework.aidl
Android/android-sdk-linux_86/platforms/android-4/framework.aidl
Android/android-sdk-linux_86/platforms/android-6/framework.aidl
...
      

這個

framework.aidl

檔案也很腦殘,雖說注釋不是很重要,但是這個代碼根本就沒有半點自我解釋能力,也不寫個注釋說明自己有什麼用途--

到此,-p參數确認

革命遠未結束,要想解決這個豬血問題,還要知道-I參數的寫法。

繼續看上面

PreCompilerBuilder.java

檔案的896行

for
 (IPath
 p : sourceFolders) {
  IFolder
 f = wsRoot.getFolder(p);
  command[index++
] = "
-I"

 +
 f.getLocation().toOSString(); //
$NON-NLS-1$

}
      

我想你能看出這是什麼意思來了,就是你項目的source目錄,一般來說是src那個目錄

至此,問題解決,最後總結下使用aidl指令行工具的方法就是

$ aidl -I/path/to/project/src -p/path/to/framework.aidl Interface.aidl
      

謝謝國家,打完收工

繼續閱讀