Android應(yīng)用程序是通過(guò)消息來(lái)驅(qū)動(dòng)的,系統(tǒng)為每一個(gè)應(yīng)用程序維護(hù)一個(gè)消息隊(duì)例,應(yīng)用程序的主線程不斷地從這個(gè)消息隊(duì)例中獲取消息(Looper),然后對(duì)這些消息進(jìn)行處理(Handler),這樣就實(shí)現(xiàn)了通過(guò)消息來(lái)驅(qū)動(dòng)應(yīng)用程序的執(zhí)行,本文將詳細(xì)分析Android應(yīng)用程序的消息處理機(jī)制。
2.Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析
在應(yīng)用程序中,我們都是把Server實(shí)現(xiàn)為Service的形式,并且通過(guò)IServiceManager.addService接口來(lái)把這個(gè)Service添加到Service Manager,Client也是通過(guò)IServiceManager.getService接口來(lái)獲得Service接口,接著就可以使用這個(gè)Service提供的功能了,這個(gè)與運(yùn)行時(shí)庫(kù)的Binder接口是一致的。
3.Android實(shí)現(xiàn)雙進(jìn)程守護(hù)(通過(guò)jni實(shí)現(xiàn))
做過(guò)android開(kāi)發(fā)的人應(yīng)該都知道應(yīng)用會(huì)在系統(tǒng)資源匱乏的情況下被系統(tǒng)殺死!當(dāng)后臺(tái)的應(yīng)用被系統(tǒng)回收之后,如何重新恢復(fù)它呢?
4.守護(hù)線程
import java.io.IOException;
/*
* 守護(hù)線程在沒(méi)有用戶線程可服務(wù)時(shí)自動(dòng)離開(kāi)
* 在Java中比較特殊的線程是被稱為守護(hù)(Daemon)線程的低級(jí)別線程。
* 這個(gè)線程具有最低的優(yōu)先級(jí),用于為系統(tǒng)中的其它對(duì)象和線程提供服務(wù)。
* 將一個(gè)用戶線程設(shè)置為守護(hù)線程的方式是在線程對(duì)象創(chuàng)建之前調(diào)用線程對(duì)象的setDaemon方法。
* 典型的守護(hù)線程例子是JVM中的系統(tǒng)資源自動(dòng)回收線程,
* 我們所熟悉的Java垃圾回收線程就是一個(gè)典型的守護(hù)線程,
* 當(dāng)我們的程序中不再有任何運(yùn)行中的Thread,
* 程序就不會(huì)再產(chǎn)生垃圾,垃圾回收器也就無(wú)事可做,
* 所以當(dāng)垃圾回收線程是Java虛擬機(jī)上僅剩的線程時(shí),Java虛擬機(jī)會(huì)自動(dòng)離開(kāi)。
* 它始終在低級(jí)別的狀態(tài)中運(yùn)行,用于實(shí)時(shí)監(jiān)控和管理系統(tǒng)中的可回收資源。
* 守護(hù)進(jìn)程(Daemon)是運(yùn)行在后臺(tái)的一種特殊進(jìn)程。它獨(dú)立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。
* 也就是說(shuō)守護(hù)線程不依賴于終端,但是依賴于系統(tǒng),與系統(tǒng)“同生共死”。
* 那Java的守護(hù)線程是什么樣子的呢。
* 當(dāng)JVM中所有的線程都是守護(hù)線程的時(shí)候,JVM就可以退出了;
* 如果還有一個(gè)或以上的非守護(hù)線程則JVM不會(huì)退出。
*/
public class testThread extends Thread {
public testThread() {
}
/** *//**
* 線程的run方法,它將和其他線程同時(shí)運(yùn)行
*/
public void run(){
for(int i = 1; i <= 100; i++){
try{
Thread.sleep(100);
} catch (InterruptedException ex){
ex.printStackTrace();
}
System.out.println(i);
}
}
public static void main(String [] args){
testThread test = new testThread();
test.setDaemon(true);
test.start();
System.out.println("isDaemon = " + test.isDaemon());
try {
System.in.read(); // 接受輸入,使程序在此停頓,一旦接收到用戶輸入,main線程結(jié)束,守護(hù)線程自動(dòng)結(jié)束
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
關(guān)于用戶線程和守護(hù)線程:在Java中有兩類(lèi)線程:User Thread(用戶線程)、Daemon Thread(守護(hù)線程) Daemon的作用是為其他線程的運(yùn)行提供便利服務(wù),比如垃圾回收線程就是一個(gè)很稱職的守護(hù)者。User和Daemon兩者幾乎沒(méi)有區(qū)別,唯一的不同之處就在于虛擬機(jī)的離開(kāi):如果 User Thread已經(jīng)全部退出運(yùn)行了,只剩下Daemon Thread存在了,虛擬機(jī)也就退出了。 因?yàn)闆](méi)有了被守護(hù)者,Daemon也就沒(méi)有工作可做了,也就沒(méi)有繼續(xù)運(yùn)行程序的必要了。 收起**
5.Android Service與Thread的應(yīng)用場(chǎng)景
Android中應(yīng)該使用Service而不應(yīng)該使用線程,Android中有提供后臺(tái)運(yùn)行的組件,叫Service。servie是系統(tǒng)的組件,它由系統(tǒng)進(jìn)程托管(servicemanager);它們之間的通信類(lèi)似于client和server,是一種輕量級(jí)的ipc通信,這種通信的載體是binder,它是在linux層交換信息的一種ipc。而thread是由本應(yīng)用程序托管。Thread:Thread 是程序執(zhí)行的最小單元,它是分配CPU的基本單位。可以用 Thread 來(lái)執(zhí)行一些異步的操作。Service:Service 是android的一種機(jī)制,當(dāng)它運(yùn)行的時(shí)候如果是Local Service,那么對(duì)應(yīng)的Service 是運(yùn)行在主進(jìn)程的 main 線程上的。如:onCreate,onStart 這些函數(shù)在被系統(tǒng)調(diào)用的時(shí)候都是在主進(jìn)程的 main 線程上運(yùn)行的。如果是Remote Service,那么對(duì)應(yīng)的 Service 則是運(yùn)行在獨(dú)立進(jìn)程的 main 線程上。
6.Intent標(biāo)志FLAG_ACTIVITY_NEW_TASK的解釋
Android Intent.FLAG_NEW_TASK詳解,包括其他的標(biāo)記的一些解釋
當(dāng)使用這個(gè)標(biāo)志時(shí),如果一個(gè)包含此activity的task已經(jīng)運(yùn)行了,新的activity不會(huì)啟動(dòng);同時(shí),當(dāng)前的task將簡(jiǎn)單的被提到窗口最前面。查看FLAG_ACTIVITY_MULTIPLE_TASK可以禁止這個(gè)行為。
這個(gè)標(biāo)志不能用在調(diào)用者需要正在登陸的activity返回一個(gè)結(jié)果的情況。
7.Activity的四種launchMode
Activity一共有以下四種launchMode:
1.standard
2.singleTop
3.singleTask
4.singleInstance
8.Java中的static關(guān)鍵字解析
static方法就是沒(méi)有this的方法。在static方法內(nèi)部不能調(diào)用非靜態(tài)方法,反過(guò)來(lái)是可以的。而且可以在沒(méi)有創(chuàng)建任何對(duì)象的前提下,僅僅通過(guò)類(lèi)本身來(lái)調(diào)用static方法。這實(shí)際上正是static方法的主要用途。
static關(guān)鍵字還有一個(gè)比較關(guān)鍵的作用就是 用來(lái)形成靜態(tài)代碼塊以優(yōu)化程序性能。static塊可以置于類(lèi)中的任何地方,類(lèi)中可以有多個(gè)static塊。在類(lèi)初次被加載的時(shí)候,會(huì)按照static塊的順序來(lái)執(zhí)行每個(gè)static塊,并且只會(huì)執(zhí)行一次。
為什么說(shuō)static塊可以用來(lái)優(yōu)化程序性能,是因?yàn)樗奶匦?只會(huì)在類(lèi)加載的時(shí)候執(zhí)行一次。因此,很多時(shí)候會(huì)將一些只需要進(jìn)行一次的初始化操作都放在static代碼塊中進(jìn)行。
9.淺析Java中的final關(guān)鍵字
在Java中,final關(guān)鍵字可以用來(lái)修飾類(lèi)、方法和變量(包括成員變量和局部變量)。
10.Java內(nèi)部類(lèi)詳解
為什么在Java中需要內(nèi)部類(lèi)?總結(jié)一下主要有以下四點(diǎn):
a.每個(gè)內(nèi)部類(lèi)都能獨(dú)立的繼承一個(gè)接口的實(shí)現(xiàn),所以無(wú)論外部類(lèi)是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類(lèi)都沒(méi)有影響。內(nèi)部類(lèi)使得多繼承的解決方案變得完整,
b.方便將存在一定邏輯關(guān)系的類(lèi)組織在一起,又可以對(duì)外界隱藏。
c.方便編寫(xiě)事件驅(qū)動(dòng)程序
d.方便編寫(xiě)線程代碼
最重要的原因之一,內(nèi)部類(lèi)的存在使得Java的多繼承機(jī)制變得更加完善。
11.借口和抽象類(lèi)的區(qū)別
1、抽象類(lèi)和接口都不能直接實(shí)例化,如果要實(shí)例化,抽象類(lèi)變量必須指向?qū)崿F(xiàn)所有抽象方法的子類(lèi)對(duì)象,接口變量必須指向?qū)崿F(xiàn)所有接口方法的類(lèi)對(duì)象。
2、抽象類(lèi)要被子類(lèi)繼承,接口要被類(lèi)實(shí)現(xiàn)。
3、接口只能做方法申明,抽象類(lèi)中可以做方法申明,也可以做方法實(shí)現(xiàn)
4、接口里定義的變量只能是公共的靜態(tài)的常量,抽象類(lèi)中的變量是普通變量。
5、抽象類(lèi)里的抽象方法必須全部被子類(lèi)所實(shí)現(xiàn),如果子類(lèi)不能全部實(shí)現(xiàn)父類(lèi)抽象方法,那么該子類(lèi)只能是抽象類(lèi)。同樣,一個(gè)實(shí)現(xiàn)接口的時(shí)候,如不能全部實(shí)現(xiàn)接口方法,那么該類(lèi)也只能為抽象類(lèi)。
6、抽象方法只能申明,不能實(shí)現(xiàn)。abstract void abc();不能寫(xiě)成abstract void abc(){}。
7、抽象類(lèi)里可以沒(méi)有抽象方法
8、如果一個(gè)類(lèi)里有抽象方法,那么這個(gè)類(lèi)只能是抽象類(lèi)
9、抽象方法要被實(shí)現(xiàn),所以不能是靜態(tài)的,也不能是私有的。
10、接口可繼承接口,并可多繼承接口,但類(lèi)只能單根繼承。