<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                原文出處——>[Android應用程序的Activity啟動過程簡要介紹和學習計劃](http://blog.csdn.net/luoshengyang/article/details/6685853) 在Android系統中,Activity和Service是應用程序的核心組件,它們以松藕合的方式組合在一起構成了一個完整的應用程序,這得益于應用程序框架層提供了一套完整的機制來協助應用程序啟動這些Activity和Service,以及提供Binder機制幫助它們相互間進行通信。在前面的文章Android進程間通信(IPC)機制Binder簡要介紹和學習計劃和Android系統在新進程中啟動自定義服務過程(startService)的原理分析中,我們已經系統地介紹了Binder機制和Service的啟動過程了,在本文中,簡要介紹Activity的啟動過程以及后續學習計劃。 在Android系統中,有兩種操作會引發Activity的啟動,一種用戶點擊應用程序圖標時,Launcher會為我們啟動應用程序的主Activity;應用程序的默認Activity啟動起來后,它又可以在內部通過調用startActvity接口啟動新的Activity,依此類推,每一個Activity都可以在內部啟動新的Activity。通過這種連鎖反應,按需啟動Activity,從而完成應用程序的功能。 這里,我們通過一個具體的例子來說明如何啟動Android應用程序的Activity。Activity的啟動方式有兩種,一種是顯式的,一種是隱式的,隱式啟動可以使得Activity之間的藕合性更加松散,因此,這里只關注隱式啟動Activity的方法。 首先在Android源代碼工程的packages/experimental目錄下創建一個應用程序工程目錄Activity。關于如何獲得Android源代碼工程,請參考在Ubuntu上下載、編譯和安裝Android最新源代碼一文;關于如何在Android源代碼工程中創建應用程序工程,請參考在Ubuntu上為Android系統內置Java應用程序測試Application Frameworks層的硬件服務一文。這里,工程名稱就是Activity了,它定義了一個路徑為shy.luo.activity的package,這個例子的源代碼主要就是實現在這里了。下面,將會逐一介紹這個package里面的文件。 應用程序的默認Activity定義在src/shy/luo/activity/MainActivity.java文件中: ~~~ package shy.luo.activity; import shy.luo.activity.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private final static String LOG_TAG = "shy.luo.activity.MainActivity"; private Button startButton = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); startButton = (Button)findViewById(R.id.button_start); startButton.setOnClickListener(this); Log.i(LOG_TAG, "Main Activity Created."); } @Override public void onClick(View v) { if(v.equals(startButton)) { Intent intent = new Intent("shy.luo.activity.subactivity"); startActivity(intent); } } } ~~~ 它的實現很簡單,當點擊它上面的一個按鈕的時候,就會啟動另外一個名字為“shy.luo.activity.subactivity”的Actvity。 名字為“shy.luo.activity.subactivity”的Actvity實現在src/shy/luo/activity/SubActivity.java文件中: ~~~ package shy.luo.activity; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class SubActivity extends Activity implements OnClickListener { private final static String LOG_TAG = "shy.luo.activity.SubActivity"; private Button finishButton = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sub); finishButton = (Button)findViewById(R.id.button_finish); finishButton.setOnClickListener(this); Log.i(LOG_TAG, "Sub Activity Created."); } @Override public void onClick(View v) { if(v.equals(finishButton)) { finish(); } } } ~~~ 它的實現也很簡單,當點擊上面的一個銨鈕的時候,就結束自己,回到前面一個Activity中去。 這里我們可以看到,Android應用程序架構中非常核心的一點:MainActivity不需要知道SubActivity的存在,即它不直接擁有SubActivity的接口,但是它可以通過一個字符串來告訴應用程序框架層,它要啟動的Activity的名稱是什么,其它的事情就交給應用程序框架層來做,當然,應用程序框架層會根據這個字符串來找到其對應的Activity,然后把它啟動起來。這樣,就使得Android應用程序中的Activity藕合性很松散,從而使得Android應用程序的模塊性程度很高,并且有利于以后程序的維護和更新,對于大型的客戶端軟件來說,這一點是非常重要的。 當然,應用程序框架能夠根據名字來找到相應的Activity,是需要應用程序本身來配合的,這就是要通過應用程序的配置文件AndroidManifest.xml來實現了: ~~~ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="shy.luo.activity" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SubActivity" android:label="@string/sub_activity"> <intent-filter> <action android:name="shy.luo.activity.subactivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> </manifest> ~~~ 從這個配置文件中,我們可以看到,MainActivity被配置成了應用程序的默認Activity,即用戶在手機屏幕上點擊Activity應用程序圖標時,Launcher就會默認啟動MainActivity這個Activity: ~~~ <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ~~~ 這個配置文件也將名字“shy.luo.activity.subactivity”和SubActivity關聯了起來,因此,應用程序框架層能夠根據名字來找到它: ~~~ <activity android:name=".SubActivity" android:label="@string/sub_activity"> <intent-filter> <action android:name="shy.luo.activity.subactivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> ~~~ 下面再列出這個應用程序的界面配置文件和字符串文件。 界面配置文件在res/layout目錄中,main.xml文件對應MainActivity的界面: ~~~ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:id="@+id/button_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/start" > </Button> </LinearLayout> ~~~ 而sub.xml對應SubActivity的界面: ~~~ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:id="@+id/button_finish" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/finish" > </Button> </LinearLayout> ~~~ 字符串文件位于res/values/strings.xml文件中: ~~~ <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Activity</string> <string name="sub_activity">Sub Activity</string> <string name="start">Start sub-activity</string> <string name="finish">Finish activity</string> </resources> ~~~ 最后,我們還要在工程目錄下放置一個編譯腳本文件Android.mk: ~~~ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := Activity include $(BUILD_PACKAGE) ~~~ 這樣,整個例子的源代碼實現就介紹完了,接下來就要編譯了。有關如何單獨編譯Android源代碼工程的模塊,以及如何打包system.img,請參考如何單獨編譯Android源代碼中的模塊一文。 執行以下命令進行編譯和打包: ~~~ USER-NAME@MACHINE-NAME:~/Android$ mmm packages/experimental/Activity USER-NAME@MACHINE-NAME:~/Android$ make snod ~~~ 這樣,打包好的Android系統鏡像文件system.img就包含我們前面創建的Activity應用程序了。 再接下來,就是運行模擬器來運行我們的例子了。關于如何在Android源代碼工程中運行模擬器,請參考在Ubuntu上下載、編譯和安裝Android最新源代碼一文。 執行以下命令啟動模擬器: ~~~ USER-NAME@MACHINE-NAME:~/Android$ emulator ~~~ 模擬器啟動起,就可以在屏幕上看到Activity應用程序圖標了: ![](http://hi.csdn.net/attachment/201108/14/0_13133026926IYI.gif) 點擊Activity這個應用程序圖標后,Launcher就會把MainActivity啟動起來: ![](http://hi.csdn.net/attachment/201108/14/0_1313303791VrbM.gif) 點擊上面的Start sub-activity銨鈕,MainActivity內部就會通過startActivity接口來啟動SubActivity: ~~~ Intent intent = new Intent("shy.luo.activity.subactivity"); startActivity(intent); ~~~ 如下圖所示: ![](http://hi.csdn.net/attachment/201108/14/0_131330397835ee.gif) 無論是通過點擊應用程序圖標來啟動Activity,還是通過Activity內部調用startActivity接口來啟動新的Activity,都要借助于應用程序框架層的ActivityManagerService服務進程。在前面一篇文章Android系統在新進程中啟動自定義服務過程(startService)的原理分析中,我們已經看到,Service也是由ActivityManagerService進程來啟動的。在Android應用程序框架層中,ActivityManagerService是一個非常重要的接口,它不但負責啟動Activity和Service,還負責管理Activity和Service。 Android應用程序框架層中的ActivityManagerService啟動Activity的過程大致如下圖所示: ![](https://box.kancloud.cn/c3240e44d84640f762501e02e36ab38a_638x730.jpg) 在這個圖中,ActivityManagerService和ActivityStack位于同一個進程中,而ApplicationThread和ActivityThread位于另一個進程中。其中,ActivityManagerService是負責管理Activity的生命周期的,ActivityManagerService還借助ActivityStack是來把所有的Activity按照后進先出的順序放在一個堆棧中;對于每一個應用程序來說,都有一個ActivityThread來表示應用程序的主進程,而每一個ActivityThread都包含有一個ApplicationThread實例,它是一個Binder對象,負責和其它進程進行通信。 下面簡要介紹一下啟動的過程: * Step 1. 無論是通過Launcher來啟動Activity,還是通過Activity內部調用startActivity接口來啟動新的Activity,都通過Binder進程間通信進入到ActivityManagerService進程中,并且調用ActivityManagerService.startActivity接口; * Step 2. ActivityManagerService調用ActivityStack.startActivityMayWait來做準備要啟動的Activity的相關信息; * Step 3. ActivityStack通知ApplicationThread要進行Activity啟動調度了,這里的ApplicationThread代表的是調用ActivityManagerService.startActivity接口的進程,對于通過點擊應用程序圖標的情景來說,這個進程就是Launcher了,而對于通過在Activity內部調用startActivity的情景來說,這個進程就是這個Activity所在的進程了; * Step 4. ApplicationThread不執行真正的啟動操作,它通過調用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中,看看是否需要創建新的進程來啟動Activity; * Step 5. 對于通過點擊應用程序圖標來啟動Activity的情景來說,ActivityManagerService在這一步中,會調用startProcessLocked來創建一個新的進程,而對于通過在Activity內部調用startActivity來啟動新的Activity來說,這一步是不需要執行的,因為新的Activity就在原來的Activity所在的進程中進行啟動; * Step 6. ActivityManagerServic調用ApplicationThread.scheduleLaunchActivity接口,通知相應的進程執行啟動Activity的操作; * Step 7. ApplicationThread把這個啟動Activity的操作轉發給ActivityThread,ActivityThread通過ClassLoader導入相應的Activity類,然后把它啟動起來。 這樣,Android應用程序的Activity啟動過程就簡要介紹到這里了,在接下來的兩篇文章中,我們將根據Activity的這兩種啟動情景,深入到應用程序框架層的源代碼里面去,一步一步地分析它們的啟動過程: 1. Android應用程序啟動過程的源代碼分析; 2. Android應用程序內部啟動Activity過程(startActivity)的源代碼分析。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看