編輯:關於Android編程
我們知道Android是以一個Activity為單位的,但是我們並沒有看到一個Activity是怎麼開始啟動的。今天我 們就從Android的源代碼開始講吧。
Android的一個apk在打開時,使用到的第一個類就是這個類。我們先來說這個類。等說完這個類就能了解Android應用程序的啟動原理了。這貨名字取名有一個Thread結尾,貌似是一個線程類。其實他並不是一個線程類,這個類沒有繼承任何類。或者說是直接繼承在Object類。我們來看ActivityThread源碼:
public final class ActivityThread {
....
}
這是ActivityThread定義時候的的源碼,可以看出他根本沒有繼承任何類。那他為什麼要以Thread來結尾的。貌似很不合理。其實不然。想必大家應該Android的異步線程機制吧。其實ActivityThread在創建的時候同時也啟動了一個線程,這個線程就是一個異步線程,他創建出了MessageQueue,並同時進行消息的輪詢,因此當這個應用程序在運行時,這個線程是一直都在的。這個線程就是應用程序的主線程,UI的處理等都是在這個線程處理的。
在AcitivityThread這個類的是有一個main方法的。我們知道java應用程序的入口就是main方法。這就是程序的入口。我們來看ActivityThread的源代碼:
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
Process.setArgV0("");
//關鍵部分,看這裡
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
其他的部分我們先不要管,先看關鍵部分,就是我注釋的那個地方。在這裡先是使用Looper.prepareMainLooper();
方法來創建一個MessageQueue實例。prepareMainLooper內部會調用prepare()方法創建消息隊列(MessageQueue)。創建出來之後,就會創建一個ActivityThread對象。這個ActivityThread對象內部會創建出一個Handler和一個ApplicationThread對象,其中這兩個對象稍後會介紹,(這裡應該有一個中斷向量,或者然後再啟一個線程去講解Handler對象和Application對象,哈哈)先壓一壓。在創建出這個ActivityThread對象之後。中間部分略過不表。之後這裡會調用Looper.loop(),是消息隊裡進行循環。所以說這個ActivityThread是一直都在的,因為需要一直等待取其他線程發過來的消息。這個線程就是我們的主線程。Activity,Service等的管理都是在這裡。之後會介紹。
好了,這個過程想必大家都了解了,現在我們說一說我們的Handler和ApplicationThread。在ActivityThread中的這個Handler其實是一個內部類,類名是H,對,就是H一個字母,他是繼承自Handler對象的。我們來看一下源代碼:
在第3行,在這裡我們可以看到,他創建了一個H類的實例。注意,這裡是類的成員變量區域,不是在某個方法裡面。意思就是這個類在創建的同時,這個mH對象就創建出來了。所以說這個mH相當於是主線程的,也就是在main裡創建出來的。而這個對象是用於其他線程想主線程發消息的。我們再來看看main函數中我們沒有提到的那部分:
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTa
我們在if語句裡面可以看到這樣一個語句sMainThreadHandler = thread.getHandler();
thread是剛剛創建出來的ActivityThread實例,而getHandler方法返回的正是mH實例。
接下來說一下ApplicationThread這個類,該類是ActivityThread的內部類,該類的作用是什麼呢。其實這裡涉及到了進程間的通信,這個類是負責接收遠程的AmS(ActivitymanagerService)IPC(進程間通信)調用的。而這個的調用一般是Android系統去調用的,這個相當於一種進程間通信,Android系統會有一個服務,用於監控用戶的操作等,當用戶進行相關操作是會通過進程之間的通信去通知這個應用程序做相應的反應,比如啟動一個Activity。當這個類收到通知之後,接下來就會安排Activity的啟動,我們可以看一下這個類的源代碼:
這裡貼出其中的部分代碼,注意不是這個類的全部代碼,只是其中的一部分。我們看一下其中的第二個方法
schedulePauseActivity
該方法的意思應該是“安排暫停activity”,該方法就是讓Activity調用onPause的代碼。下面的其他代碼也都是類似的。都是管理service和activity的代碼,在這些方法的內部都會調用sendMessage,而這個方法的內部又會繼續調用mh.sendMessage()。將暫停或者啟動Activity的相關消息安排到主線程的MessageQueue隊列中,等待消息隊列輪詢來處理該消息。我們可以從這些方法的名字也能看出來,schedule是安排的意思,“安排暫停activity”就表示你把“暫停activity”這件事安排一下,等MessageQueue手頭的事忙完,再來處理“暫停activity”的事。而安排這件事的人是誰呢,就是mH這個助理了,由他把消息發送給MessageQueue。
雖然只是模仿,但我覺得這是學習自定義view的必經之路,所以還是把我所學到的東西拿出來與大家一起分享。先貼出一張progressBar的gif圖,其中有水平的進度條,和圓
前面我們已經將每個月的收支明細存入到SQLite的數據表中,本文將實現從SQLite的數據表中取出這些數據顯示為賬單明細界面。 &nbs
序最近在學習有關如何porting sensor的東西,僅借此機會寫博客來督促自己進步,當然如果,有人對博客提出不同的理解,我覺得這是極好的,大家可以共同進步。在這一期的
效果圖:這個對框完全繼承、仿照AlertDialog,只是實現了自定義效果。另外,沒有實現setIcon,因為iphone中的對話框多數都沒有圖標。附件包含例子、jar包