欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      Android源碼編譯整理總結(jié)

      時間:2019-05-12 03:56:45下載本文作者:會員上傳
      簡介:寫寫幫文庫小編為你整理了多篇相關的《Android源碼編譯整理總結(jié)》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《Android源碼編譯整理總結(jié)》。

      第一篇:Android源碼編譯整理總結(jié)

      1.必要的軟件環(huán)境

      sudo apt-get install build-essential sudo apt-get install make sudo apt-get install gcc sudo apt-get install g++ sudo apt-get install libc6-dev sudo apt-get install patch sudo apt-get install texinfo sudo apt-get install libncurses-dev sudo apt-get install git-core gnupg sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl sudo apt-get install ncurses-dev sudo apt-get install zlib1g-dev sudo apt-get install valgrind sudo apt-get install python2.5

      筆者發(fā)現(xiàn)這里已經(jīng)比較全來,不過還有一些應該是linux系統(tǒng)自帶的,如果缺少就按照提示install一下

      安裝java環(huán)境,這里有必要說一下,大家裝環(huán)境的時候很多人會一起裝,不過筆者建議java和其他的分開,因為裝java很可能會失敗,從而導致其他的也fail sudo apt-get install sun-java6-jdk

      這里就說到上面說很多人會安裝java失敗的問題,筆者也是從網(wǎng)上找的解決辦法現(xiàn)在一起整理出來:

      ubuntu10.04 lucid 去掉了sun-java6-jre,sun-java6-jdk的源,所以如果是直接apt-get install 提示是

      現(xiàn)在沒有可用的軟件包 sun-java6-jdk,但是它被其它的軟件包引用了。

      這可能意味著這個缺失的軟件包可能已被廢棄,或者只能在其他發(fā)布源中找到

      E: 軟件包 sun-java6-jdk 還沒有可供安裝的候選者

      解決辦法(選擇一個即可):

      1、系統(tǒng)->系統(tǒng)管理->軟件源->“其它軟件”下添加一個 deb http://archive.canonical.com/ lucid partner

      之后,再執(zhí)行apt-get install 如果是下載java5就添加deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse”

      2、自己從sun網(wǎng)站下載相應的Jre,JDK安裝即可

      3、從新立德軟件管理器中search openJDK,用openJDK代替

      注: 官方文檔說如果用sun-java6-jdk可出問題,得要用sun-java5-jdk。經(jīng)測試發(fā)現(xiàn),如果僅僅make(make不包括make sdk),用sun-java6-jdk是沒有問題的。而make sdk,就會有問題,嚴格來說是在make doc出問題,它需要的javadoc版本為1.5。

      因此,我們安裝完sun-java6-jdk后最好再安裝sun-java5-jdk,或者 只安裝sun-java5-jdk。這里sun-java6-jdk和sun-java5-jdk都安裝,并只修改javadoc.1.gz和 javadoc。因為只有這兩個是make sdk用到的。這樣的話,除了javadoc工具是用1.5版本,其它均用1.6版本: sudo apt-get install sun-java5-jdk 修改javadoc的link cd /etc/alternatives sudo rm javadoc.1.gz

      sudo ln-s /usr/lib/jvm/java-1.5.0-sun/man/man1/javadoc.1.gz javadoc.1.gz sudo rm javadoc sudo ln-s /usr/lib/jvm/java-1.5.0-sun/bin/javadoc javadoc

      2、設置環(huán)境變量 vim ~/.bashrc 在.bashrc中新增或整合PATH變量,如下 #java 程序開發(fā)/運行的一些環(huán)境變量 JAVA_HOME=/usr/lib/jvm/java-6-sun JRE_HOME=${JAVA_HOME}/jre export ANDROID_JAVA_HOME=$JAVA_HOME export CLASSPATH=.:${JAVA_HOME}/lib:$JRE_HOME/lib:$CLASSP ATH export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin export JAVA_HOME;export JRE_HOME;export CLASSPATH;HOME_BIN=~/bin/ export PATH=${PATH}:${JAVA_PATH}:${JRE_PATH}:${HOME_BIN};#echo $PATH;最后,同步這些變化: source ~/.bashr 3.安裝repo(用來更新android源碼)

      創(chuàng)建~/bin目錄,用來存放repo程序,如下: $ cd ~ $ mkdir bin 并加到環(huán)境變量PATH中,在第2步中已經(jīng)加入 下載repo腳本并使其可執(zhí)行:

      $ curl http://android.git.kernel.org/repo >~/bin/repo $ chmod a+x ~/bin/repo 4.初始化repo

      repo是android對git的一個封裝,簡化了一些git的操作。創(chuàng)建工程目錄: $ mkdir android $ cd android repo初始化

      $ repo init-u git://android.git.kernel.org/platform/manifest.git 這里包含了android最新的源碼

      在此過程中需要輸入名字和email地址。初始化成功后,會顯示: repo initialized in /android 在~/android下會有一個.repo的隱藏目錄。

      如果想拿某個branch而不是主線上的代碼,我們需要用-b參數(shù)制定branch名字,比如:

      repo init-u git://android.git.kernel.org/platform/manifest.git-b cupcake 這 里抓下來的分支是cupcake,網(wǎng)上關于編譯到文章大多是針對cupcake分支,是andoird 1.5版本,但是之前我沒有輸入后面的參數(shù),以致于下到的代碼是主線上的代碼,是android 2.1版本。兩者目錄結(jié)構有一些差別,導致當我按照網(wǎng)上的說明步驟來執(zhí)行遇到錯誤時,不知道是版本不同的原因還是其他什么原因。因此很奇怪為什么網(wǎng)上的文 章都是說cupcake的,而沒有怎么講主線的源代碼編譯。5.同步源代碼 $ repo sync 這一步要很久,要看個人的網(wǎng)絡速度

      6.編譯android源碼,并得到~/android/out目錄 $ cd ~/andoird

      $ make-j2 筆者的電腦是雙核所以是-j2,以此類推8核就可以-j8 這一過程很久,主要看機器的配置

      如果是cupcake,那么直接make的時候,會出現(xiàn)以下錯誤:

      1.frameworks/policies/base/PolicyConfig.mk:22: *** No module defined for the given PRODUCT_POLICY(android.policy_phone).Stop.錯誤。

      解決辦法:

      在build/tools/findleaves.sh中的第89行,這一句find “${@:0:$nargs}” $findargs-type f-name “$filename”-print |

      改為find “${@:1:$nargs-1}” $findargs-type f-name “$filename”-print |

      2.frameworks/base/tools/aidl/AST.cpp:10: error: 'fprintf' was not declared in this scope的錯誤

      解決辦法:

      下載gcc-4.3和g++-4.3

      apt-get install gcc-4.3 g++-4.3

      因為ubuntu 9.10自帶到是gcc 4.4,因此需要重新下載gcc 4.3,最后設置gcc軟連接到gcc 4.3

      進入/usr/bin cd /usr/bin

      建個軟連接

      ln-s gcc-4.3 gcc

      ln-s g++-4.3 g++

      然后進入android目錄下,執(zhí)行make,就可以了。

      主線代碼則沒有此問題 7.在模擬器上運行編譯好的android

      編譯好android之后,emulator在~/android/out/host/linux-x86/bin 下,ramdisk.img,system.img和userdata.img則在~/android/out/target/product /generic下 $ cd ~/android/out/host/linux-x86/bin 增加環(huán)境變量 $ emacs ~/.bashrc 在.bashrc中新增環(huán)境變量,如下 #java 程序開發(fā)/運行的一些環(huán)境變量

      export ANDROID_PRODUCT_OUT=~/android/out/target/product/g eneric ANDROID_PRODUCT_OUT_BIN=~/android/out/host/linux-x 86/bin export PATH=${PATH}:${ANDROID_PRODUCT_OUT_BIN}:${ANDROID_ PRODUCT_OUT};最后,同步這些變化: $ source ~/.bashrc $ cd ~/android/out/target/product/generic

      $ emulator-system system.img-data userdata.img-ramdisk ramdisk.img 最后進入android桌面,就說明成功了。8.編譯模塊

      android中的一個應用程序可以單獨編譯,編譯后要重新生成system.img 在源碼目錄下執(zhí)行

      $.build/envsetup.sh(.后面有空格)就多出一些命令:

      -croot: Changes directory to the top of the tree.mm: Builds all of the modules in the current directory.cgrep: Greps on all local C/C++ files.resgrep: Greps on all local res/*.xml files.-godir: Go to the directory containing a file.可以加—help查看用法

      我們可以使用mmm來編譯指定目錄的模塊,如編譯聯(lián)系人: $ mmm packages/apps/Contacts/ 編完之后生成兩個文件: out/target/product/generic/data/app/ContactsTests.apk out/target/product/generic/system/app/Contacts.apk 可以使用 $ make snod 重新生成system.img,再運行模擬器 9.編譯SDK

      直接執(zhí)行make是不包括make sdk的。make sdk用來生成SDK,這樣,我們就可以用與源碼同步的SDK來開發(fā)android了。

      a)修改/frameworks/base/include/utils/Asset.h ?UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024? 改為 ?UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024?

      原因是eclipse編譯工程需要大于1.3M的buffer;

      這一步,筆者編譯的是主線程的,在Asset.h文件里沒找到上面的常量,所以就沒做這一步,但是也成功了。b)編譯ADT。

      如果想用eclipse開發(fā)android應用程序,最好是安裝ADT,這樣就可以在eclipse下創(chuàng)建android的工程。

      產(chǎn)生ADT eclipse plugins $ development/tools/eclipse/scripts/build_server.sh ~/adt/

      使用前建議設定一下ECLIPSE_HOME的環(huán)境變量,不然會以為沒有裝eclipse,然后幫你download下來。

      這里要非常注意,本人就曾經(jīng)卡在這里,始終編譯不過。一開始會提示eclipse的什么什么jar找不到,因此fail。這主要是因為我到 ECLIPSE_HOME到環(huán)境變量設置錯誤。我之前裝的eclipse只從新力得上面抓下來的,好像找不到eclipse所在到目錄是哪個,結(jié)果就設置 了一個名為eclipse的文件夾作為環(huán)境變量。因此后來直接從eclipse的官網(wǎng)上下了一個,以為這樣就可以。結(jié)果杯具的是下到是一個eclipse Galileo,到頭來還是提示eclipse什么什么文件找不到。最后實在沒法,索性把eclipse刪個干凈,讓程序自己去下eclipse,發(fā)現(xiàn)抓 的是eclipse ganymede。在此要鄭重說明一下,自己去下的話應該下載jee的ganymade,而不能是java 的ganymade,具體原因試試就知道了。

      主線代碼編譯ADT的時候方法相同,但是沒有development/tools/eclipse這個目錄,而是在/sdk/eclipse這個目錄 c)執(zhí)行make sdk。

      注意,這里需要的javadoc版本為1.5,所以你需要在步驟1中同時安裝sun-java5-jdk $ make sdk

      編譯很慢。編譯后生成的SDK存放在out/host/linux-x86/sdk/,此目錄下有android-sdk_eng.xxx_linux-x86.zip和android-sdk_eng.xxx_linux-x86目錄。android-sdk_eng.xxx_linux-x86就是 SDK目錄

      實際上,當用mmm命令編譯模塊時,一樣會把SDK的輸出文件清除,因此,最好把android-sdk_eng.xxx_linux-x86移出來

      此后的應用開發(fā),就在該SDK上進行,所以把7)對于~/.bashrc的修改注釋掉,增加如下一行:

      export PATH=${PATH}:~/android/out/host/linux-x86/sdk/andr oid-sdk_eng.xxx_linux-x86/tools 注意要把xxx換成真實的路徑;

      同樣筆者編譯的是主線程,所以編譯完之后,發(fā)現(xiàn)~/android/out/host/linux-x86/sdk/android-sdk_eng.x xx_linux-x86/目錄下有2個文件夾一個是tools一個是platform-tools,然后用eclipse指向這個目錄的時候會提示找不到ADB,這時候只要把platform-tools下的ADB拷貝到tools文件夾就OK了 d)關于環(huán)境變量、android工具的選擇 目前的android工具有:

      A、我們從網(wǎng)上下載的SDK,如果你下載過的話(tools下有許多android工具,lib/images下有img映像)

      B、我們用make sdk編譯出來的SDK(tools下也有許多android工具,lib/images下有img映像)

      C、我們用make編譯出來的out目錄(tools下也有許多android工具,lib/images下有img映像)

      那么我們應該用那些工具和img呢?

      首先,我們一般不會用A選項的工具和img,因為一般來說它比較舊,也源碼不同步。其次,也不會用C選項的工具和img,因為這些工具和img沒有經(jīng)過 SDK的歸類處理,會有工具和配置找不到的情況;事實上,make sdk產(chǎn)生的很多工具和img,在make編譯出來out目錄的時候,已經(jīng)編譯產(chǎn)生了,make sdk只是做了copy而已。e)安裝、配置ADT

      ~/adt/android-eclipse/下的文件壓縮,然后從eclipse中install就行了,當然還有其他方法 10.編譯linux內(nèi)核映像 a)準備交叉編譯工具鏈

      android代碼樹中有一個prebuilt項目,包含了我們編譯內(nèi)核所需的交叉編譯工具。b)設定環(huán)境變量 $ emacs ~/.bashrc 增加如下兩行:

      export PATH=$PATH:~/android/prebuilt/linux-x86/toolchain/ arm-eabi-4.4.0/bin export ARCH=arm 保存后,同步變化: $ source ~/.bashrc c)獲得合適的內(nèi)核源代碼 $ cd ~/android 獲得內(nèi)核源代碼倉庫

      $ git clone git://android.git.kernel.org/kernel/common.git kernel $ cd kernel $ git branch 顯示 * android-2.6.27

      說明你現(xiàn)在在android-2.6.27這個分支上,也是kernel/common.git的默認主分支。顯示所有head分支: $ git branch-a 顯示 * android-2.6.27 remotes/origin/HEAD-> origin/android-2.6.27 remotes/origin/android-2.6.25 remotes/origin/android-2.6.27 remotes/origin/android-2.6.29 remotes/origin/android-goldfish-2.6.27 remotes/origin/android-goldfish-2.6.29

      我們選取最新的android-goldfish-2.6.29,其中goldfish是android的模擬器模擬的CPU。

      $ git checkout-b android-goldfish-2.6.29 origin/android-goldfish-2.6.29 $ git branch 顯示 android-2.6.27 * android-goldfish-2.6.29 我們已經(jīng)工作在android-goldfish-2.6.29分支上了。d)設定交叉編譯參數(shù)

      打開kernel目錄下的Makefile文件,把CROSS_COMPILE指向剛才下載的prebuilt中的arm-eabi編譯器

      CROSS_COMPILE ?= arm-eabi-把 LDFLAGS_BUILD_ID = $(patsubst-Wl$(comma)%,%, $(call ld-option,-Wl$(comma)build-id,))

      這一行注釋掉,并且添加一個空的LDFLAGS_BUILD_ID定義,如下: LDFLAGS_BUILD_ID = e)編譯內(nèi)核映像 $ cd ~/android/kernel $ make goldfish_defconfig $ make f)測試生成的內(nèi)核映像

      $ emulator-avd myavd-kernel ~/android/kernel/arch/arm/boot/zImage

      第二篇:Ubuntu 11.10編譯Android源碼錯誤

      Ubuntu 11.10編譯Android源碼錯誤

      問題1:

      frameworks/base/libs/utils/RefBase.cpp: 在成員函數(shù)

      ‘void android::RefBase::weakref_type::trackMe(bool, bool)’中:

      frameworks/base/libs/utils/RefBase.cpp:483:67: 錯誤: 將

      ‘constandroid::RefBase::weakref_impl’作為

      ‘voidandroid::RefBase::weakref_impl::trackMe(bool, bool)’的‘this’實參時丟棄了類型限定[-fpermissive]

      make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libutils_intermediates/RefBase.o] 錯誤 1 原因:Ubuntu 11.10的gcc 4.6版本太高了,android編譯需要gcc 4.4

      解決辦法:更換gcc、g++版本4.6為4.4

      sudo apt-get install gcc-4.4

      sudo apt-get install g++-4.4

      sudo rm-rf /usr/bin/gcc /usr/bin/g++

      sudo ln-s /usr/bin/gcc-4.4 /usr/bin/gcc

      sudo ln-s /usr/bin/g++-4.4 /usr/bin/g++

      問題2:

      g++: 錯誤: –fpermissive:沒有那個文件或目錄

      make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libutils_intermediates/RefBase.o] 錯誤 1 解決辦法:sudoapt-get install g++-4.4-multilib

      經(jīng)過此操作編譯可順利進行。

      第三篇:android有關sensor的源碼總結(jié)

      android有關sensor的源碼總結(jié)

      雖然這篇文章寫得很差,因為趕時間,所以就匆匆忙忙地寫出來自己作一個筆記。但是我想對大家應該有一點幫助。

      1、有關sensor在Java應用程序的編程(以注冊多個傳感器為例,這程序是我臨時弄出來的,可能有錯)

      package com.sensors.acc;

      import android.app.Activity;import android.os.Bundle;

      import android.util.Log;import android.widget.TextView;import android.hardware.SensorManager;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;

      public class acc extends Activity { float x, y, z;SensorManager sensormanager = null;Sensor accSensor = null;Sensor lightSensor = null;Sensor proximitySensor = null;TextView accTextView = null;/** Called when the activity is first created.*/ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.main);sensormanager =(SensorManager)getSystemService(SENSOR_SERVICE);accSensor = sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT);proximitySensor = sensormanager.getDefaultSensor(Sensor.TYPE_PROXIMITY);accTextView =(TextView)findViewById(R.id.textview_name);}

      SensorEventListener lsn = new SensorEventListener(){ public void onSensorChanged(SensorEvent e){ if(e.sensor == accSensor){ Log.d(“sensor”, “found acc sensor”);x = e.values[SensorManager.DATA_X];y = e.values[SensorManager.DATA_Y];z = e.values[SensorManager.DATA_Z];accTextView.setText(“x = ” + x + “, ny = ” + y + “, nz = ” + z);} else if(e.sensor == lightSensor){ Log.d(“sensor”, “found light sensor”);accTextView.setText(“data is ” + e.values[0]);} else if(e.sensor == proximitySensor){ Log.d(“sensor”, “found proximity sensor”);accTextView.setText(“distance is ” + e.values[0]);} }

      public void onAccuracyChanged(Sensor s, int accuracy){ } };@Override protected void onResume(){ super.onResume();// register this class as a listener for the orientation and accelerometer sensors sensormanager.registerListener(lsn, accSensor, SensorManager.SENSOR_DELAY_NORMAL);sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);sensormanager.registerListener(lsn, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);// sensormanager.unregisterListener(lsn);} @Override protected void onStop(){ // unregister listener sensormanager.unregisterListener(lsn, accSensor);sensormanager.unregisterListener(lsn, lightSensor);sensormanager.unregisterListener(lsn, proximitySensor);super.onStop();} }

      在onCreate()函數(shù)中,調(diào)用getSystemService(SENSOR_SERVICE)初始化一個SensorManager實例,為什么要用getSystemService函數(shù),而不直接用new SensorManager呢?我們看此函數(shù)的實現(xiàn),在ApplicationContext.java中,if(SENSOR_SERVICE.equals(name)){ return getSensorManager();然后getSensorManager()的實現(xiàn)

      private SensorManager getSensorManager(){ synchronized(mSync){ if(mSensorManager == null){ mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());} } return mSensorManager;} 看到?jīng)]有?初始化SensorManager的時候需要mMainThread.getHandler().getLooper()這個參數(shù),之個應該是用來傳遞消息用的,在SensorManager類的構造函數(shù)中會把此參數(shù)傳給類成員mMainLooper。如果用new SensorManager()就需要另外獲取mainLooper參數(shù)傳遞進去。

      2、在android中跟sensor有關的一些文件有SensorManager.java,位于frameworksbasecorejavaandroidhardware目錄下,SensorService.java,位于frameworksbaseservicesjavacomandroidserver目錄下,android_hardware_SensorManager.cpp,位于frameworksbasecorejni目錄下,與SensorManager.java相對應,com_android_server_SensorService.cpp,在frameworksbaseservicesjni目錄下,與SensorService.java相對應。還有SystemServer.java文件,HardwareLibhardwareIncludeHardware目錄下的Sensor.h頭文件。另外我們需要根據(jù)Sensor.h實現(xiàn)自己的一個源文件,一般取名為sensors_xxx.c或者sensors_xxx.cpp。

      3、SensorManager類分析 有幾個函數(shù)比較重要,必須清晰理解它們的實現(xiàn),才能了解整個傳感器系統(tǒng)的實現(xiàn)。從而更好地去實現(xiàn)硬件抽象層的實現(xiàn)。幾個比較重要的函數(shù)有構造函數(shù)SensorManager(), registerListener()和unregisterListener(),其中registerListener()和unregisterListener()有多個,標志為 @Deprecated的是過時的,就不要看了。(1)構造函數(shù)SensorManager(Looper mainLooper)這個函數(shù)首先獲取得傳感器系統(tǒng)服務,并賦給類成員mSensorService,mSensorService = ISensorService.Stub.asInterface(ServiceManager.getService(Context.SENSOR_SERVICE));這里我要說一句,就是關于這個傳感器系統(tǒng)服務,很多書上都說用getSystemService()是獲得傳感器的系統(tǒng)服務,而它返回的是SensorManager類型,所以以為整個系統(tǒng)都是使用同一個SensorManager類的實例,以為我們在任何地方使用的SensorManager實例都是同一個,它們的公共成員是共享的。但是經(jīng)過這兩天的分析,這種說法是錯誤的。其實每次調(diào)用getSystemService()函數(shù)時都初始化一個新的SensorManager實例,而這個SensorManager實例會在構造函數(shù)里通過取得傳感器系統(tǒng)服務SensorService來實現(xiàn)對下層傳感器的一些控制。而這個SensorService才是系統(tǒng)的傳感器服務,說服務,不如說它只是SensorService類的一個實例罷了。它只在系統(tǒng)初始化時初始化一次。Android中的系統(tǒng)服務機制應該跟傳感器的都差不多一個樣,都是由不同的Manager調(diào)用下層相同的Service。你可以列舉其它的Manager。那它是什么時候初始化呢?它是系統(tǒng)初始化在SystemServer進程里創(chuàng)建的,SystemServer是一個管理很多系統(tǒng)服務的進程,我們轉(zhuǎn)到SystemServer.的main函數(shù)里,可以看到一直到調(diào)用int2()函數(shù),它會創(chuàng)建一個ServerThread,最終調(diào)用AdbSettingsObserver類的run()函數(shù),在run()函數(shù)里有這么有一句

      // Sensor Service is needed by Window Manager, so this goes first Log.i(TAG, “Sensor Service”);ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context));這里就創(chuàng)建SensorService實例了。在創(chuàng)建這個實例時會在SensorService構造函數(shù)中調(diào)用jni函數(shù) public SensorService(Context context){ if(localLOGV)Log.d(TAG, “SensorService startup”);_sensors_control_init();} 我們看_sensors_control_init();對應的為 static jint android_init(JNIEnv *env, jclass clazz){ sensors_module_t* module;if(hw_get_module(SENSORS_HARDWARE_MODULE_ID,(const hw_module_t**)&module)== 0){ if(sensors_control_open(&module->common, &sSensorDevice)== 0){ const struct sensor_t* list;int count = module->get_sensors_list(module, &list);return count;} } return 0;} 它主要調(diào)用了sensor.h中的sensors_control_open()static inline int sensors_control_open(const struct hw_module_t* module, struct sensors_control_device_t** device){ return module->methods->open(module, SENSORS_HARDWARE_CONTROL,(struct hw_device_t**)device);} 之后在系統(tǒng)任何地方使用的都是這個SensorService實例。最后run()函數(shù)調(diào)用Looper.loop();就進行消息循環(huán)等待了,這就是SystemServer進程的消息服務了。這才真正叫做系統(tǒng)服務嘛。

      我們繼續(xù)看SensorManager類的構造函數(shù),取得SensorService后,nativeClassInit();這是一個jni函數(shù),SensorManager類調(diào)用的jni函數(shù)都在com_android_server_SensorService.cpp里,我們看這函數(shù) static void nativeClassInit(JNIEnv *_env, jclass _this){ jclass sensorClass = _env->FindClass(“android/hardware/Sensor”);SensorOffsets& sensorOffsets = gSensorOffsets;sensorOffsets.name = _env->GetFieldID(sensorClass, “mName”, “Ljava/lang/String;”);sensorOffsets.vendor = _env->GetFieldID(sensorClass, “mVendor”, “Ljava/lang/String;”);sensorOffsets.version = _env->GetFieldID(sensorClass, “mVersion”, “I”);sensorOffsets.handle = _env->GetFieldID(sensorClass, “mHandle”, “I”);sensorOffsets.type = _env->GetFieldID(sensorClass, “mType”, “I”);sensorOffsets.range = _env->GetFieldID(sensorClass, “mMaxRange”, “F”);sensorOffsets.resolution = _env->GetFieldID(sensorClass, “mResolution”,“F”);sensorOffsets.power = _env->GetFieldID(sensorClass, “mPower”, “F”);} 這個函數(shù)只是獲取和設置一些信息吧,我們不關心。接著 sensors_module_init();我們看這函數(shù) static jint sensors_module_init(JNIEnv *env, jclass clazz){ int err = 0;sensors_module_t const* module;err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,(const hw_module_t **)&module);if(err == 0)sSensorModule =(sensors_module_t*)module;return err;} 它獲取了sensor的模塊信息,并把它賦給sSensorModule全局變量,之后傳的modules參數(shù)都為這個。接著在構造函數(shù)里

      final ArrayList fullList = sFullSensorsList;int i = 0;do { Sensor sensor = new Sensor();i = sensors_module_get_next_sensor(sensor, i);

      if(i>=0){ Log.d(TAG, “found sensor: ” + sensor.getName()+ “, handle=” + sensor.getHandle());sensor.setLegacyType(getLegacySensorType(sensor.getType()));fullList.add(sensor);sHandleToSensor.append(sensor.getHandle(), sensor);} } while(i>0);這里主要是通過jni函數(shù)sensors_module_get_next_sensor(sensor, i);獲取傳感器列表,并把它加入自己的fullList列表中。我們看sensors_module_get_next_sensor()函數(shù) static jint sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next){ if(sSensorModule == NULL)return 0;

      SensorOffsets& sensorOffsets = gSensorOffsets;const struct sensor_t* list;int count = sSensorModule->get_sensors_list(sSensorModule, &list);if(next >= count)return-1;

      list += next;

      jstring name = env->NewStringUTF(list->name);jstring vendor = env->NewStringUTF(list->vendor);env->SetObjectField(sensor, sensorOffsets.name, name);env->SetObjectField(sensor, sensorOffsets.vendor, vendor);env->SetIntField(sensor, sensorOffsets.version, list->version);env->SetIntField(sensor, sensorOffsets.handle, list->handle);env->SetIntField(sensor, sensorOffsets.type, list->type);env->SetFloatField(sensor, sensorOffsets.range, list->maxRange);env->SetFloatField(sensor, sensorOffsets.resolution, list->resolution);env->SetFloatField(sensor, sensorOffsets.power, list->power);next++;return next } 它主要是調(diào)用HAL層的get_sensors_list()函數(shù)取得傳感器列表信息。接著在sensorManger構造函數(shù)最后

      sSensorThread = new SensorThread();創(chuàng)建一個SensorThread()線程。但并未運行,但在SensorThread類的構造函數(shù)里會執(zhí)行jni函數(shù) sensors_data_init();我們看此函數(shù)static jint sensors_data_init(JNIEnv *env, jclass clazz){ if(sSensorModule == NULL)return-1;int err = sensors_data_open(&sSensorModule->common, &sSensorDevice);return err;} 它調(diào)用了HAL層的sensors_data_open函數(shù),而這個函數(shù)位于sensor.h中,它調(diào)用的是 static inline int sensors_data_open(const struct hw_module_t* module, struct sensors_data_device_t** device){ return module->methods->open(module, SENSORS_HARDWARE_DATA,(struct hw_device_t**)device);} Modules->methods->open函數(shù)。而在SensorThread類的析構函數(shù)finalize()里會調(diào)用 sensors_data_uninit();static jint sensors_data_uninit(JNIEnv *env, jclass clazz){ int err = 0;if(sSensorDevice){ err = sensors_data_close(sSensorDevice);if(err == 0)sSensorDevice = 0;} return err;} 在sensor.h里

      static inline int sensors_data_close(struct sensors_data_device_t* device){ return device->common.close(&device->common);} 那什么時候sSensorThread線程會運行呢?我們在下面看registerListener()函數(shù)。

      (2)public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate){ return registerListener(listener, sensor, rate, null);} 它調(diào)用的是 public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler)在這函數(shù)中,先驗證rate,然后檢測注冊的listener在不在本類的sListeners列表中。for(ListenerDelegate i : sListeners){ if(i.getListener()== listener){ l = i;break;} } 如果不在就申請一個listener,并把它加入全局列表sListener中,并調(diào)用mSensorService的enableSensor()函數(shù)使能傳感器,這個enableSensor()函數(shù)最終會調(diào)用HAL層的active函數(shù)和set_delay()函數(shù),使用后然后判斷sListener列表是否為空,當然,第一次為空時加入一個新的listener就不為空了,此時就執(zhí)行sSensorThread的startLocked運行sSensorThread線程了

      l = new ListenerDelegate(listener, sensor, handler);result = mSensorService.enableSensor(l, name, handle, delay);if(result){ sListeners.add(l);sListeners.notify();} if(!sListeners.isEmpty()){ sSensorThread.startLocked(mSensorService);} 另一方面,如果注冊的listener在sListeners列表中,則先調(diào)用mSensorService的enableSensor()函數(shù)使能傳感器,然后把注冊的傳感器加入到已存在的listener中。result = mSensorService.enableSensor(l, name, handle, delay);if(result){ l.addSensor(sensor);} 接下來我們看看startLocked函數(shù),它在SensorThread中,void startLocked(ISensorService service){ try { if(mThread == null){ Bundle dataChannel = service.getDataChannel();mThread = new Thread(new SensorThreadRunnable(dataChannel), SensorThread.class.getName());mThread.start();} } catch(RemoteException e){ Log.e(TAG, “RemoteException in startLocked: ”, e);} } 第一次mThread為null,然后它調(diào)用了service.getDataChannel()函數(shù),此函數(shù)在SensorService類中,主要調(diào)用了jni函數(shù)_sensors_control_open(),public Bundle getDataChannel()throws RemoteException { // synchronize so we do not require sensor HAL to be thread-safe.synchronized(mListeners){ return _sensors_control_open();} } SensorService類中調(diào)用的jni函數(shù)主要都在com_android_server_SensorService.cpp文件 中,我們看一下這個函數(shù) static jobject android_open(JNIEnv *env, jclass clazz){ native_handle_t* handle = sSensorDevice->open_data_source(sSensorDevice);if(!handle){ return NULL;}

      // new Bundle()jobject bundle = env->NewObject(gBundleOffsets.mClass, gBundleOffsets.mConstructor);

      if(handle->numFds > 0){ jobjectArray fdArray = env->NewObjectArray(handle->numFds, gParcelFileDescriptorOffsets.mClass, NULL);for(int i = 0;i < handle->numFds;i++){ // new FileDescriptor()jobject fd = env->NewObject(gFileDescriptorOffsets.mClass, gFileDescriptorOffsets.mConstructor);env->SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle->data[i]);// new ParcelFileDescriptor()jobject pfd = env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fd);env->SetObjectArrayElement(fdArray, i, pfd);} // bundle.putParcelableArray(“fds”, fdArray);env->CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray, env->NewStringUTF(“fds”), fdArray);}

      if(handle->numInts > 0){ jintArray intArray = env->NewIntArray(handle->numInts);env->SetIntArrayRegion(intArray, 0, handle->numInts, &handle->data[handle->numInts]);// bundle.putIntArray(“ints”, intArray);env->CallVoidMethod(bundle, gBundleOffsets.mPutIntArray, env->NewStringUTF(“ints”), intArray);}

      // delete the file handle, but don't close any file descriptors native_handle_delete(handle);return bundle;} 它主要調(diào)用了HAL層的open_data_source()函數(shù)。取得一些文件描述符等信息。接下來SensorThread創(chuàng)建一個線程,調(diào)用start()就進入SensorThreadRunnable類的run()函數(shù)了,所以我們接著去看run()函數(shù),它首先調(diào)用open()函數(shù) if(!open()){ return;} 在open()函數(shù)中調(diào)用了 jni函數(shù)sensors_data_open(fds, ints);static jint sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray){ jclass FileDescriptor = env->FindClass(“java/io/FileDescriptor”);jfieldID fieldOffset = env->GetFieldID(FileDescriptor, “descriptor”, “I”);int numFds =(fdArray ? env->GetArrayLength(fdArray): 0);int numInts =(intArray ? env->GetArrayLength(intArray): 0);native_handle_t* handle = native_handle_create(numFds, numInts);int offset = 0;

      for(int i = 0;i < numFds;i++){ jobject fdo = env->GetObjectArrayElement(fdArray, i);if(fdo){ handle->data[offset++] = env->GetIntField(fdo, fieldOffset);} else { handle->data[offset++] =-1;} } if(numInts > 0){ jint* ints = env->GetIntArrayElements(intArray, 0);for(int i = 0;i < numInts;i++){ handle->data[offset++] = ints[i];} env->ReleaseIntArrayElements(intArray, ints, 0);}

      // doesn't take ownership of the native handle return sSensorDevice->data_open(sSensorDevice, handle);} 這函數(shù)最終調(diào)用了HAL層的data_open(),之后run()函數(shù)就進入一個while循環(huán)了。while(true){ // wait for an event final int sensor = sensors_data_poll(values, status, timestamp);

      int accuracy = status[0];synchronized(sListeners){ if(sensor ==-1 || sListeners.isEmpty()){ if(sensor ==-1){ // we lost the connection to the event stream.this happens // when the last listener is removed.Log.d(TAG, “_sensors_data_poll()failed, we bail out.”);}

      // we have no more listeners or polling failed, terminate the thread sensors_data_close();mThread = null;break;} final Sensor sensorObject = sHandleToSensor.get(sensor);if(sensorObject!= null){ // report the sensor event to all listeners that // care about it.final int size = sListeners.size();for(int i=0;i ListenerDelegate listener = sListeners.get(i);if(listener.hasSensor(sensorObject)){ // this is asynchronous(okay to call // with sListeners lock held).listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);} } } } 它調(diào)用了jni函數(shù)sensors_data_poll()一直讀數(shù)據(jù)。static jint sensors_data_poll(JNIEnv *env, jclass clazz, jfloatArray values, jintArray status, jlongArray timestamp){ sensors_data_t data;int res = sSensorDevice->poll(sSensorDevice, &data);if(res >= 0){ jint accuracy = data.vector.status;env->SetFloatArrayRegion(values, 0, 3, data.vector.v);env->SetIntArrayRegion(status, 0, 1, &accuracy);env->SetLongArrayRegion(timestamp, 0, 1, &data.time);}

      return res;} 把傳感器得到的值都放在value數(shù)組中,根據(jù)返回的傳感器標志sensor,把它分派給在sListener列表中所有的listener,如果listener中有監(jiān)聽這個sensor,就把它分派給這個listener,此時就會引起onSensorChange()了。

      好了,獲取傳感器數(shù)據(jù)主要是這樣一個途徑。最后我們?nèi)シ治鲆幌聈nregisterListener()函數(shù)。

      private void unregisterListener(Object listener){ if(listener == null){ return;} try { synchronized(sListeners){ final int size = sListeners.size();for(int i=0;i ListenerDelegate l = sListeners.get(i);if(l.getListener()== listener){ // disable all sensors for this listener for(Sensor sensor : l.getSensors()){ String name = sensor.getName();int handle = sensor.getHandle();mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE);} sListeners.remove(i);break;} } } } catch(RemoteException e){ Log.e(TAG, “RemoteException in unregisterListener: ”, e);} } 不用想這個函數(shù)會做一些與registerListener相反的事情,至少差不多。它先在sListeners列表中找到這個listener,然后先調(diào)用enableSensor()函數(shù)禁止這個傳感器。我們跟蹤一下這函數(shù),在SensorService類中。synchronized(mListeners){ if(enable!=SENSOR_DISABLE &&!_sensors_control_activate(sensor, true)){ Log.w(TAG, “could not enable sensor ” + sensor);return false;}

      Listener l = null;int minDelay = enable;for(Listener listener : mListeners){ if(binder == listener.mToken){ l = listener;} if(minDelay > listener.mDelay)minDelay = listener.mDelay;}

      if(l == null && enable!=SENSOR_DISABLE){ l = new Listener(binder);binder.linkToDeath(l, 0);mListeners.add(l);mListeners.notify();}

      if(l == null){ // by construction, this means we're disabling a listener we // don't know about...Log.w(TAG, “l(fā)istener with binder ” + binder + “, doesn't exist(sensor=” + name + “, id=” + sensor + “)”);return false;}

      if(minDelay >= 0){ _sensors_control_set_delay(minDelay);}

      if(enable!= SENSOR_DISABLE){ l.addSensor(sensor, enable);} else { l.removeSensor(sensor);deactivateIfUnusedLocked(sensor);if(l.mSensors == 0){ mListeners.remove(l);binder.unlinkToDeath(l, 0);mListeners.notify();} }

      if(mListeners.size()== 0){ _sensors_control_wake();_sensors_control_close();} } return true;你們看到它的實現(xiàn)了吧。如果enable是true的話,就調(diào)用_sensors_control_activate(),如果是false的話,就調(diào)用deactivateIfUnusedLocked(),它們最終都會調(diào)用 HAL層的active()函數(shù)。最后,如果是禁止傳感器的話,如果mListeners為空了,它就會調(diào)用 _sensors_control_wake();_sensors_control_close();這兩個jni函數(shù),最終會調(diào)用HAL層的wake()和close_data_source()函數(shù)。當調(diào)用wake()函數(shù)時,會使SensorManager類線程的run()函數(shù)中的sensor_data_poll()函數(shù)立即返回,此時在run()函數(shù)中調(diào)用sensors_data_close();最終會調(diào)用HAL層的data_close()函數(shù)。至此,一個傳感器從初始到結(jié)束的流程就分析完了。

      所以在java使用一個傳感器在HAL層具體調(diào)用的函數(shù)流程為: 首先,sensors_control_open(),只在系統(tǒng)初始化時調(diào)用一次。用來初始化control_device結(jié)構體。

      以下的是每次使用傳感器一般經(jīng)過的流程,注意,是一般而已,有些并不執(zhí)行(1)sensors_data_open(2)get_sensors_list(3)activate(4)set_delay(5)open_data_source(6)data_open(7)poll 一直讀數(shù)據(jù)。。。。。。退出時(8)activate(9)sensors_control_close(10)data_close

      當然其它的細節(jié)你們可以繼續(xù)去研究。也可以在我博客里提出來大家交流和討論一下!發(fā)表于 @ 2010年04月15日 09:25:00 | 評論(15 AddFeedbackCountStack(“5487476”))| 編輯| 舉報| 收藏

      var CurrentEntryId = '5487476';var CurArticleTitle = '閱讀android有關sensor的源碼總結(jié)';var AllowComment = 'True';var AllowAnonymousComment = /^true$/i.test('False');匿名用戶 發(fā)表于Saturday, April 24, 2010 4:10:24 PM IP:舉報回復刪除挺好的,可是我有一點疑問呢?匿名用戶 發(fā)表于Wednesday, May 05, 2010 10:44:44 AM IP:舉報回復刪除代碼中怎么沒有看到hal stub的東西啊?我想知道open等操作的具體實現(xiàn)(非kenne層)匿名用戶 發(fā)表于Thursday, May 06, 2010 11:42:40 PM IP:舉報回復刪除回復 匿名用戶: check sensors_device_open()in sensor.c 匿名用戶 發(fā)表于Friday, May 07, 2010 12:12:08 AM IP:舉報回復刪除我看了詳細代碼,講得很好。流程大概就是這樣了。估計你沒有hal層代碼,因為那是芯片廠商提供或者自己寫的。很難寫。匿名用戶 發(fā)表于Saturday, May 08, 2010 12:04:55 AM IP:舉報回復刪除Hal usually has folling functions: 1.Sampling Device manager notifies sensor drivers via ioctl to refresh sensor data.Sensor drivers usually utialize i2c bus API functions(i.e.i2c_transfer())to fetch data.2.Reporting After sampling, sensor device drivers report sensor data through input device via input device API functions(i.e.input_report_xxx()and input_sync())3.in sensor_xxx.c or sensor_xxx.cpp, dev->device.poll = sensors_data_poll;sensors_data_poll()is a static function to pick sensor, poll and read sensor data.In Platform: 1.in android_hardware_SensorManager.cpp jni function sensors_data_poll()is provided for SensorManager.java to poll sensor data.sensors_data_poll()actually calls sensors_data_poll()in sensor_xxx.c /sensor_xxx.cpp.2.In SensorManager.java.registerListener()would call sSensorThread.startLocked().sSensorThread.startLocked()would create a new thread based on SensorThreadRunnable()that calls sensors_data_poll().3.In SensorThreadRunnable()listener.onSensorChangedLocked()is called to notify the Sensor event listener after polling sensor data.tigerhily 發(fā)表于Thursday, June 03, 2010 10:08:06 PM IP:舉報回復刪除jerry: 講得真好!頂一個。請問你有HAL的具體實現(xiàn)嗎?我想?yún)⒖家幌??;蛘咧v講sensors_data_open(3)activate(4)set_delay(5)open_data_source(6)data_open(7)poll 這些接口的具體實現(xiàn)!謝謝匿名用戶 發(fā)表于Saturday, June 05, 2010 12:15:03 AM IP:舉報回復刪除Tigerhily: 1.poll()is usually via input_event.Please get poll()reference from EventHup.cpp is you do not have sensor_xxx.c or sensor_xxx.cpp.input_event is device independent abstraction layer provided by the kernel.2.set_delay()starts from SensorManager.java, it calls native delay function in snesor_xxx.c or sensor_xxx.cpp.sensor_xxx.c or sensor_xxx.cpp calls ioctl to set delay value to sendor device driver.sensor device driver usually creates a miscdevice to accept ioctl command.3.Sensor device driver utilizes delay to adjust sampling rate and retrieves data via i2c bus and saves the data via input_event to let application pull sensor data.tigerhily 發(fā)表于Sunday, June 06, 2010 8:48:21 PM IP:舉報回復刪除回復 匿名用戶:hi jerry:Thanks for your help.Actually I don't have sensro_xxx.c and i am going to implement it.I will try and consult if needed.Thanks.lz_fine 發(fā)表于Tuesday, August 03, 2010 2:08:17 PM IP:舉報回復刪除你好,我現(xiàn)在也在做這塊,但是我遇到一個問題,我在HAL層的sensor.c中control__activate()函數(shù)中打開設備文件/dev /sensor成功,并且能執(zhí)行ioctl操作,但是到了data__poll()函數(shù)中再執(zhí)行ioctl就失敗了,報告的錯誤是Bad file number,errno是EBADF,看起來好像是這個fd被關閉了,這個怎么也想不通,因為看起來SensorThread還在跑,而且在 sensor.c中也沒有執(zhí)行close操作,這種情況有沒有遇到過啊,能解釋一下嗎,感激不盡lz_fine 發(fā)表于Wednesday, August 04, 2010 3:55:43 PM IP:舉報回復刪除找到ioctl失敗的原因了,是在SensorManager.java中關閉fd的,不過正常情況下sensor.c中應該先復制一個fd,因此加上一句復制fd的語句就可以了,終于搞定了,內(nèi)牛滿面啊iceskyang 發(fā)表于Thursday, August 05, 2010 11:02:16 AM IP:舉報回復刪除問一下,如果加入后臺進程用來輔助計算加速度磁場的值,那么這個進程為什么會在一開機后就運行的。我在int.rc中明明設置了disabled。

      第四篇:32位Ubuntu 11.10下android2.3.7源碼下載與編譯小結(jié)

      32位Ubuntu 11.10下android2.3.7源碼下載與編譯小結(jié)

      1、我是在vmware下安裝ubuntu 11.10的,這個網(wǎng)上資料很多,不多說了。我給ubuntu分了25g硬盤和1g內(nèi)存。

      2、請參照http://source.android.com/source。初始化編譯環(huán)境 檢查一下包是否安裝: Python 2.4-2.7 Git 1.5.4 或更高版本

      沒有話可以sudo apt-get install..安裝一下

      JDK 6 因為是編譯android2.3以上,如果編譯2.2以下需要JDK5 安裝JDK6:

      $ sudo add-apt-repository“deb http://archive.canonical.com/ lucid partner” $ sudo apt-get update $ sudo apt-get install sun-java6-jdk 如果下載速度不行,可以先把ubuntu的更新源改成網(wǎng)易的源,可參考:http://bolg.malu.me/html/2010/279.html。其他需要安裝的包:

      我安裝了如下包:官網(wǎng)上那是64位需要安裝的包,我是32位的有些不一樣。

      $ sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev x11proto-core-dev libx11-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils

      3、下面開始下載源碼

      首先安裝repo(是一個便于git管理的工具)$ mkdir~/bin $ PATH=~/bin:$PATH $ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo $ chmod a+x~/bin/repo 初始化repo client $ mkdir android2.3.7 $ cd android2.3.7 初始化repo,我是使用的下面的地址,使用官網(wǎng)地址時出現(xiàn)了網(wǎng)絡錯誤

      $ repo init-u http://android.googlesource.com/platform/manifest.git-b android-2.3.7_r1

      按照提示輸入用戶名和郵箱。接著 $ repo sync 開始同步源碼,根據(jù)你的網(wǎng)速,我的持續(xù)了50分鐘左右。

      還有一步驗證git tags可參照官網(wǎng)。下完后就可以在剛才創(chuàng)建的android2.3.7文件夾下看見已下載的源碼。

      4、開始編譯 初始化:

      $ source build/envsetup.sh $ lunch full-eng 上面代表編譯的一個target,full是針對emulator編譯全部包括app、輸入法等,eng是指針對開發(fā)者編譯,有最高權限。具體可參見官網(wǎng)。

      接著就可以編譯了,在源碼目錄下直接make就行,需要一段時間。編譯過程中有幾個問題需要指出一下: 問題1:

      由于我們是32位系統(tǒng),所以有些文件需要修改一下:將./external/clearsilver/cgi/Android.mk./external/clearsilver/java-jni/Android.mk./external/clearsilver/util/Android.mk./external/clearsilver/cs/Android.mk 四個文件中的

      LOCAL_CFLAGS+=-m64 LOCAL_LDFLAGS+=-m64

      注釋掉,或者將“64”換成“32”

      LOCAL_CFLAGS+=-m32 LOCAL_LDFLAGS+=-m32

      然后,將./build/core/main.mk 中的

      ifneq(64,$(findstring64,$(build_arch)))

      改為:

      ifneq(i686,$(findstring i686,$(build_arch)))

      問題2:

      frameworks/base/libs/utils/RefBase.cpp:483:67: android::RefBase::weakref_impl?

      as

      ?this?

      error:

      passing

      of

      ?const ?void

      argument android::RefBase::weakref_impl::trackMe(bool, bool)? discards qualifiers [-fpermissive] make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libutils_intermediates/RefBase.o] error 1 如下解決:

      $ gedit frameworks/base/libs/utils/Android.mk 將下面一行

      LOCAL_CFLAGS+=-DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)改成

      LOCAL_CFLAGS+=-DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)–fpermissive 問題3:

      :0:0: warning: “_FORTIFY_SOURCE” redefined [enabled by default]

      :0:0: note: this is the location of the previous definition cc1plus: all warnings being treated as errors make: *** [out/host/linux-x86/obj/EXECUTABLES/obbtool_intermediates/Main.o] Error 1 這是由于11.10的gcc

      版本過高造成的,可參考這篇文章修改:http://hi.baidu.com/designhouse/blog/item/fec5cdbf8d6a231618d81fc1.html。至此編譯完畢。

      make編譯的并不是所有內(nèi)容,不包含內(nèi)核和SDK。映像生成在out/target/product/generic

      下:android

      源碼編譯后得到system.img,ramdisk.img,userdata.img映像文件。其中,ramdisk.img是一個分區(qū)映像文件,在kernel啟動時,ramdisk被用來調(diào)用init,以及把真正的root file system mount起來。system.img包括了主要系統(tǒng),系統(tǒng)app等,會被掛載到/下,可對應查看./system該目錄,可以發(fā)現(xiàn)在其下app/下有一些系統(tǒng)自帶的應用程序。userdata.img包括了一些用戶數(shù)據(jù),被掛載到/data下,對應可查看./data/目錄,emulator加載這3個映像文件。

      5、編譯SDK 編譯SDK可以得到與源碼同步的SDK,還會生成一些tools,在源碼根目錄下:

      $ sudo make PRODUCT-sdk-sdk 編譯生成的SDK在out/host/linux-x86/SDK下。之后如果在ubuntu下使用eclipse進行開發(fā),可以使用你編譯的SDK。

      下面就在模擬器中運行鏡像,建議切到root用戶下,首先配置幾個環(huán)境變量,將自己編譯的SDK設為優(yōu)先級最高,在源碼根目錄下執(zhí)行:

      $sudo update-alternatives

      --install/usr/bin/AndroidSDK

      AndroidSDK

      /home/zhaolin/AndroidSource_GB/out/host/linux-x86/sdk/android-sdk_eng.root_linux-x86255 這樣會在/etc/alternatives下生成一個指向該SDK目錄的軟連接AndroidSDK,這個目錄主要存放一些系統(tǒng)默認打開的程序的信息和配置。那么/usr/bin/AndroidSDK就指向這個軟連接。接著執(zhí)行:

      gedit~/.bashrc 在文件末尾添加:

      export ANDROID_SDK_HOME=/usr/bin/AndroidSDK export PATH=$ANDROID_SDK_HOME/tools:$PATH export ANDROID_PRODUCT_OUT=~/android2.3.7/out/target/product/generic 接著就可以執(zhí)行:

      $ emulator 運行的就是你編譯的映像。執(zhí)行emulator 命令時,如果不帶任何參數(shù),則Linux Kernel鏡像默認使用~/Android/prebuilt/android-arm/kernel目錄下的kernel-qemu文件,而

      Android鏡像文件則默認使用ANDROID_PRODUCT_OUT目錄下的system.img、userdata.img和ramdisk.img。模擬器運行需要這四個文件,如果你編譯了內(nèi)核則可以使用自己的Kernel鏡像,可用于android移植等。

      6、單獨編譯模塊

      如果你不想編譯整個系統(tǒng),就想編譯某一個應用程序,可以使用mmm命令,使用之前,在源碼目錄下先要執(zhí)行:

      $ build/envsetup.sh

      這樣會生成一些命令,有m即make、mm編譯當前目錄下所有模塊、mmm編譯指定目錄下所有模塊。你可以把packages/apps/Music應用的application name改成MyMusic(AndroidManifest.xml中),然后執(zhí)行:

      $ mmm packages/apps/Music 在out/target/product/generic/system/app中就可以看見Music.apk,然后執(zhí)行:

      $ make snod 重新生成system.img。

      第五篇:Android總結(jié)

      Android四大組件:

      Activity—表現(xiàn)屏幕界面

      Service—后臺服務

      BroadcastReceiver—實現(xiàn)廣播機制

      ContentProvider—實現(xiàn)數(shù)據(jù)存儲

      Intent類:用來啟動程序并傳遞信息的類

      用于Activity、Receiver、Service之間進行交互的類,通過無參構造方法創(chuàng)建對象,增加其action、category、data、extra等屬性進行信息傳遞,并通過Activity中的startActivity(Intent intent)進行界面的跳轉(zhuǎn);通過Context中的StartService(Intent intent)進行服務跳轉(zhuǎn);通過Context中的registerReceive(Intent intent)對廣播進行注冊,并通過sendBroadcast()進行無序消息發(fā)送,或可以通過SendOrderedBroadcast()進行有序的消息發(fā)送。Handler類:

      用來發(fā)送和處理消息,并配合主線程完成UI的更新;消息Message/Runnable傳遞通過MessageQueue(消息隊列,先進先出)進行傳遞,并通過Lopper進行接收,傳遞的消息可以為Message對象,也可以是Runnable對象;接收方法通過HandleMessage(Message msg)進行獲取。SharedPreferences類:

      一般用于第一次登錄時的設置,或者是各個界面的一些小型格式設置,如字體等。是本地的小型共享數(shù)據(jù)庫,可以通過Context的靜態(tài)方法getSharedPreferences獲得其對象,對象內(nèi)的值均為鍵值對進行儲存。通過SharedPreferences對象調(diào)用editor()獲取SharedPreferences.Editor對象,向共享數(shù)據(jù)庫中增加數(shù)據(jù),putString(),并提交數(shù)據(jù),commit();通過SharedPreferences對象獲取共享數(shù)據(jù)庫中的數(shù)據(jù),getString()。

      ViewPager:實現(xiàn)界面滑動的類;

      通過設置OnPagerChangedListener設置ViewPager的監(jiān)聽事件;

      實現(xiàn)流程:

      ①布局文件中設置ViewPager控件;

      ②代碼中進行綁定控件;

      ③通過繼承PagerAdapter抽象類進行設置適配器,并傳遞數(shù)據(jù)源;

      ④適配器中實現(xiàn)兩個抽象方法,兩個重寫方法:getCount()—獲取滑動界面的數(shù)量,isViewFromObject()—判斷視圖是否是來自于Object文件中;重寫兩個方法,分別為destoryItem—銷毀指定位置的視圖;InstantiateItem(),設置指定位置的視圖;

      Timer與TimerTask類:

      Timer為計時器的類,通過無參構造方法可以獲取對象,通過Timer.schedule(TimerTask task,long time)進行設置多久后執(zhí)行某任務,當任務執(zhí)行完后,取消計時的功能,Timer.cancle();TimerTask類為抽象類,實例化時,必須重寫run方法;執(zhí)行的內(nèi)容,均在run方法中進行設置,并且執(zhí)行時,已在子線程中進行執(zhí)行。自定義View:用到的類有Paint、Canvas、Spec、SpecF、Path、View.MeasureSpec、Timer、TimerTask;

      抽象類,通過子類繼承,獲取對象;在布局文件中綁定后,通過代碼,設置自定義View的屬性;自定義View中,通過重寫OnMeasure方法,對布局文件中的尺寸進行測量,并由View中的setMeasureDimenson()方法,進行數(shù)據(jù)的保存;通過重寫Ondraw方法,進行繪圖;當需要繪制動態(tài)圖形時,使用計時器Timer的schedule(TimerTask,long time,delay time2)方法,在time時間后,每隔time2時間,重寫執(zhí)行run方法中的內(nèi)容;將耗時的操作設置在run方法中,并通過View中的invalidate()方法刷新主線程中的繪的圖形,通過postInvalidate()刷新子線程中的圖形。數(shù)據(jù)庫:

      常用的數(shù)據(jù)庫有Oracle,需要安裝和配置的大型收費數(shù)據(jù)庫;MySQL是中型數(shù)據(jù)庫,同樣需要安裝配置,但不需要收費;Sqlite是小型免費的嵌入式數(shù)據(jù)庫,占用內(nèi)存低,最新版本為3.0。Sqlite數(shù)據(jù)庫需要通過SqliteDatabaseOpenHelper進行創(chuàng)建數(shù)據(jù)庫,并通過SqliteDatabase進行數(shù)據(jù)庫的操作。輔助類是抽象類,通過繼承,重寫兩個方法,并在子類的構造方法中通過OpenHelper的構造方法(Context context,String SqlName,SqliteDatabase.CursorFactory factory,int version)進行數(shù)據(jù)庫的創(chuàng)建,在onCreate方法中,進行數(shù)據(jù)庫表的創(chuàng)建,在onUpdate中進行數(shù)據(jù)庫的版本更新。在數(shù)據(jù)庫的操作類中,執(zhí)行exect方法,通過sql語句對數(shù)據(jù)庫進行操作。Create table student(_id integer primary key auto increament ,name text);insert into student(_id,name)values(1,zx);delete from student where _id=1;update student set _id=2 where name=zx;select *from student;ListView、GridView適配器的優(yōu)化:

      將布局文件中的控件進行封裝,當視圖加載時,判斷可變視圖是否存在,當不存在時,通過布局文件獲取視圖,并新建封裝類,將地址通過setTag()進行發(fā)送;當視圖存在時,重復利用地址—getTag()。反射:

      存儲數(shù)據(jù)的方式:

      共享數(shù)據(jù)庫、數(shù)據(jù)庫、文件、網(wǎng)絡、內(nèi)容提供者

      廣播:

      廣播傳播時,需要接收者、發(fā)送者、廣播頻道;根據(jù)發(fā)送者的發(fā)送方式不同,分為有序廣播、無序廣播;有序廣播為接收者有接收順序,根據(jù)設置的優(yōu)先級不同,確定先后順序,接收者同時也是發(fā)送者,向后面的廣播發(fā)送消息,發(fā)送過程中,可以添加信息,也可以停止廣播的傳輸;無序廣播,接收者之間無聯(lián)系,均從發(fā)送者處接收信息;廣播在傳輸過程中,不能被添加信息,也不可能被停止。廣播在發(fā)送前,需要對接收者進行注冊,注冊方式有兩種,動態(tài)注冊、靜態(tài)注冊。動態(tài)注冊,是在代碼中進行,通過Context對象調(diào)用靜態(tài)方法進行注冊,所有的廣播均可以用動態(tài)注冊,其生命周期依賴于應用,相對于靜態(tài)注冊,比較節(jié)省內(nèi)存;靜態(tài)方法在清單文件中進行注冊,部分系統(tǒng)廣播不能通過靜態(tài)注冊進行,其生命周期依賴于系統(tǒng),當系統(tǒng)啟動,即運行接收廣播,較耗內(nèi)存。廣播接收者需要繼承BroadcastReceiver,并實現(xiàn)抽象方法onReceive(),通過回調(diào)接口,進行數(shù)據(jù)的傳輸。注意:廣播發(fā)送前,必須進行接收者的注冊,并且,當顯示跳轉(zhuǎn)時,不需要意圖過濾器。安卓布局:九種布局

      線性布局,水平或垂直方向兩種格式,主要特點為權重,即規(guī)定各控件在視圖中的占有的比例;

      相對布局,相對于父控件或兄弟控件的布局,各控件需指定相對位置; 絕對布局,指定各控件在視圖中的絕對位置,幾乎不再使用; 表格布局,子布局放在行中,列由控件表示(TableRow); 幀布局:覆蓋前面布局的布局,一般用于暫停按鈕等; 風格布局:可以跨行、跨列的布局,占滿換行;

      左右側(cè)滑:可以實現(xiàn)左右側(cè)滑,通過設置主菜單和二級菜單設置左右兩個菜單; 下拉刷新:設置下拉刷新、上拉加載的功能; 抽屜布局;

      安卓版本及對應的API:

      1.6—4;2—7;3—11;4—15;4.3—18;5—20;5.1—21;6—23;7—25; 安卓四層架構:

      應用層:Java語言開發(fā),主要從事App開發(fā);

      運行庫層:Java語言與C語言,View視圖、管理類等的開發(fā); 架構層:C語言與Linux語言,各種框架、瀏覽器等; 內(nèi)核層:Linux、C語言,開發(fā)各種驅(qū)動; 安卓四大組件:

      Activity:界面,實現(xiàn)程序與用戶之間的交換,有自己的生命周期,七個生命周期;4種啟動模式 Service:

      BroadcastReceive:三要素,發(fā)送者、接收者、發(fā)送頻道(Intent);類型:有序(接收有序,有數(shù)據(jù)傳送,可以攔截數(shù)據(jù))、無序廣播(相對);注冊方式:靜態(tài)注冊,持久監(jiān)聽,占用內(nèi)存比較高生命周期跟隨系統(tǒng),動態(tài)注冊(代碼中),所有廣播都可以動態(tài)注冊,部分系統(tǒng)廣播不能動態(tài)注冊,臨時監(jiān)聽,占用內(nèi)存較少,生命周期隨應用進行;

      ContentProvide:不能存放數(shù)據(jù),五種存放數(shù)據(jù)方式之一,特點為:①為數(shù)據(jù)的獲取等操作添加一個統(tǒng)一的接口②可以實現(xiàn)跨應用訪問數(shù)據(jù);③可以實現(xiàn)Android中通訊錄、消息、音頻、視頻等的訪問或操作;通過ContentReceive進行數(shù)據(jù)的訪問,可以對數(shù)據(jù)進行增刪改查操作。

      動畫: IO流: 序列化: AlertDialog:

      Set實現(xiàn)類: 手機電量檢測:

      自定義SurfaceView:

      自定義View:三個構造方法的區(qū)別

      Message:Handler.obtain/new/Message.obtain

      HttpUriConnection訪問網(wǎng)絡

      gride 異步任務 動畫

      抽象類和接口 反射 克隆 序列化 側(cè)滑的實現(xiàn) 數(shù)據(jù)庫 Socket:

      Gson解析

      異步任務和子線程區(qū)別 WebView 版本更新 照片的圓角化

      Collection與Collections Sql語句

      MVP框架與MVC: TCP與UDP的區(qū)別: 一鍵分享的流程: Http協(xié)議的理解: 不使用框架訪問網(wǎng)絡: List集合與set集合: 自定義View的流程: 線性布局的特點: ViewPager的原理: 服務的啟動方式:

      Activity的啟動方式: Xml數(shù)據(jù)解析:

      下載Android源碼編譯整理總結(jié)word格式文檔
      下載Android源碼編譯整理總結(jié).doc
      將本文檔下載到自己電腦,方便修改和收藏,請勿使用迅雷等下載。
      點此處下載文檔

      文檔為doc格式


      聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻自行上傳,本網(wǎng)站不擁有所有權,未作人工編輯處理,也不承擔相關法律責任。如果您發(fā)現(xiàn)有涉嫌版權的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進行舉報,并提供相關證據(jù),工作人員會在5個工作日內(nèi)聯(lián)系你,一經(jīng)查實,本站將立刻刪除涉嫌侵權內(nèi)容。

      相關范文推薦

        Android WebView總結(jié)(合集)

        Android WebView總結(jié) 1、添加權限:AndroidManifest.xml中必須使用許可"Android.permission.INTERNET",否則會出web page not available錯誤。 2、在要Activity中生成一個WebV......

        Android 課程總結(jié)

        一、 Android開發(fā)環(huán)境的搭建。 1、 Android SDK的安裝; 2、 ADT的安裝和配置; 3、 Android 模擬器的配置。 二、 編寫第一個Android程序───Hello World(1學時) 1、 創(chuàng)建一......

        Android方案總結(jié)

        一、硬件描述 如上圖,應用程序的開發(fā)過程中我們使用了飛思卡爾的i.MX51 EVK Hardware。 設備提供的支持如下:多標準音頻回放;多標準視頻回放;開放的系統(tǒng)支持; 二、軟體結(jié)構 1、An......

        Android面試總結(jié)

        1.activity的生命周期。 activity主要生命周期的方法說明: onCreate(Bundle savedInstanceState):創(chuàng)建activity時調(diào)用。設置在該方法中,還以Bundle的形式提供對以前儲存的任......

        Android培訓總結(jié)(定稿)

        Android培訓總結(jié) 非常高興能夠參加清華大學的Android暑期培訓,感謝老師們對我們的教導和關心,在短短一個月的時間里我學到了Java、數(shù)據(jù)庫、Android、JSP等知識。最重要的是通......

        Android 個人總結(jié)

        Android 個人總結(jié) 通過本學期的的學習,我知道了android是由google開發(fā)的一款手機平臺,android的基本架構是基于linux內(nèi)核,由內(nèi)核向外的反別為庫和應用架構,然后就是我們手機上的......

        Android學習總結(jié)

        Android學習總結(jié) 零零碎碎的總結(jié):1.客戶端的功能邏輯不難,UI界面也不難,但寫UI花的時間是寫功能邏輯的兩倍. 2.寫代碼前的思考過程非常重要,即使在簡單的功能,也需要在本子......

        Android2.3編譯問題總結(jié)

        Android2.3編譯問題總結(jié) 1. 安裝JDK 2. 獲取源代碼 cd android2.3 repo init -u git://android.git.kernel.org/platform/manifest.git -b gingerbread repo sync 3. sourc......