Android四大元件
Activities 描述UI,并且處理使用者與機器螢幕的互動。
是使用者操作的可視化界面;它為使用者提供了一個完成操作指令的視窗。當我們建立完畢Activity之後,需要調用setContentView()方法來完成界面的顯示;以此來為使用者提供互動的入口。在Android App 中隻要能看見的幾乎都要依托于Activity,是以Activity是在開發中使用最頻繁的一種元件。
Services 處理與應用程式關聯的背景操作。
Broadcast Receivers 處理Android作業系統和應用程式之間的通信。
Content Providers 處理資料和資料庫管理方面的問題。
附件元件:
Fragments 代表活動中的一個行為或者一部分使用者界面。
Views 繪制在螢幕上的UI元素,包括按鈕,清單等。
Layouts 控制螢幕格式,展示視圖外觀的View的繼承。
Intents 元件間的消息連線。
Resources 外部元素,例如字元串資源、常量資源及圖檔資源等。
Manifest 應用程式的配置檔案。
關于四大元件:
Activity元件
Activity的生命周期
1、概念:Activity是一種展示型元件,主要是向使用者展示一個界面,并且可以接收使用者的輸入資訊進而和使用者進行互動。對使用者來說,Activity就是Android應用的全部,因為其他三大元件對使用者來說是不可感覺的。
在Android中會維持一個Activity Stack(Activity棧),當一個新的Activity建立時,他就會放到
棧頂,這個Activity就處于運作狀态,當再有一個新的Activity被建立後,會重新壓入棧頂,而之前的那個
Activity會在這個Activity之下,就像子彈壓入彈匣一樣,之前的Activity就會進入背景
一個avtivity實際上有四種狀态:
1.運作中(running):這時Activity位于棧頂,是可見的,可與使用者互動的,
2.暫停(Paused):當Activity失去焦點,不能跟使用者互動了,但依然可見,就處于暫停狀态,當一個全新的非全屏的
Activity或者一個透明的Activity放到棧頂,activity就處于暫停狀态,這個時候的Activity各種資料還保留着,
隻有記憶體極低的情況下,Activity才會被删除
3.停止(Stoped):當一個Activity被另一個Activity完全覆寫,或者點選HOME鍵退出了背景,這個Activity
就處于停止狀态,這裡有些是跟暫停狀态相似的,這個時候Activity的各種資料保留着,當系統别的地方需要用到
資料時,系統會自動的去銷毀Activity
4.銷毀(Detroyed):當我們點選傳回鍵或者系統在記憶體不夠用的情況下就會把Activity從棧中移除出來進行銷毀
被系統回收,這時Activity處于銷毀狀态
##
Activity中所有的元件都要顯示的配置
其中:
name:指定Activity實作類的類名
icon:指定該Activity所對應的圖示
label:指定該Activity所對應的标簽
exported:指定該Activity對否可以被其他應用調用,如果設為true,那麼該activity講可以被其他應用調用
launchMode:指定Activity的加載模式(四種,下面)
Activity的四種加載模式:
standard
singleTop
singleTask
singleInstance
Standard:預設模式,不用寫配置,允許多個相同的執行個體,也允許多個Activity疊加
SingleTop:允許多個相同的執行個體,但不允許Activity疊加,隻允許其他Activity調用onnewIntent()方法建立新的Activity
SingTask:隻允許有一個執行個體的Activity,如果在同意個task中有多個相同的Activity,則最後啟動的Activity會自動Destroy前面的Activity
SingleInstance:隻有一個執行個體,且一個task中隻允許有這一個Activity存在,若有其他的Activity,則重新開啟一個task。
Activity之間的跳轉:
(1)顯式跳轉
首先建立一個Intent對象,調用Intent的構造方法,傳入兩個參數,第一個參數
Context要求傳入一個上下文,第二個參數Class指定要啟動的目标活動;然後調用startActivity()方法傳入Intent對象就可以啟動目标活動了。
(2)隐式跳轉
首先在AndroidManifest.xml中配置action以及category;
然後在activity中建立一個Intent對象,調用構造方法,傳入action配置的字元串,再調用addCategory()方法添加category字元串;最後調用startActivity()方法傳入Intent對象就可以啟動目标活動了,隻有和設定的action以及category完全比對的目标活動才會被啟動。
Service元件:
服務(Service)是Android中實作程式背景運作的解決方案,它非常适合去執行那些不需要和使用者互動而且還要求長期運作的任務。服務的運作不依賴于任何使用者界面,即使程式被切換到背景,或者使用者打開了另外一個應用程式,服務仍然能夠保持正常運作。
不過需要注意的是,服務并不是運作在一個獨立的程序當中的,而是依賴于建立服務時所在的應用程式程序。與某個應用程式程序被殺掉時,所有依賴于該程序的服務也會停止運作。另外.也不要被服務的背景概念所迷惑,實際上服務并不會自動開啟線程,所有的代碼都是預設運作在主線程當中的。也就是說,我們需要在服務的内部手動建立子線程,并在這裡執行具體的任務,否則就有可能出現主線程被阻塞住的情況。
1.startService和bindService的差別:
startService隻是啟動Service,啟動它的元件(如Activity)和Service并沒有關聯,隻有當Service調用stopSelf或者其他元件調用stopService服務才會終止。
bindService方法啟動Service,其他元件可以通過回調擷取Service的代理對象和Service互動,而這兩方也進行了綁定,當啟動方銷毀時,Service也會自動進行unBind操作,當發現所有綁定都進行了unBind時才會銷毀Service。
2.IntentService
IntentService相比父類Service而言,其最大特點是其回調函數Onhandleintent中可以直接進行耗時操作,不必再開線程,其原理是IntentService的成員變量,Handler在初始化時已經屬于工作流程,之後HandleMessage,包括onHandleIntent等函數都運作在工作線程中
3.Service工作流程:
onCreate():當Service第一次被建立後立即回調該方法,該方法在整個生命周期 中隻會調用一次!
onDestory():當Service被關閉時會回調該方法,該方法隻會回調一次!
onStartCommand(intent,flag,startId):早期版本是onStart(intent,startId), 當用戶端調用startService(Intent)方法時會回調,可多次調用StartService方法, 但不會再建立新的Service對象,而是繼續複用前面産生的Service對象,但會繼續回調 onStartCommand()方法!
IBinder onOnbind(intent):該方法是Service都必須實作的方法,該方法會傳回一個 IBinder對象,app通過該對象與Service元件進行通信!
onUnbind(intent):當該Service上綁定的所有用戶端都斷開時會回調該方法!
測試Service的工作流程:
1.建立Service
public class TestService extends Service {
private String TAG = "TestService";
//必須要實作的方法
@Override
public IBinder onBind(Intent intent){
Log.i(TAG,"onBind方法被調用!");
return null;
}
//Service被建立時調用
@Override
public void onCreate(){
Log.d(TAG, "onCreate: onCreate方法被調用");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
Log.i(TAG, "onStartCommand: onStartConmmand方法被調用");
return super.onStartCommand(intent,flags,startId);
}
@Override
public void onDestroy(){
Log.i(TAG, "onDestroy: onDestroy方法被調用");
super.onDestroy();
}
}
重寫Service的 onCreate()、onStartCommand()和onDestory()方法。其中 onCreate() 方法在服務建立的時候調用,onStartCommand() 方法會在每次服務啟動的時候調用,onDestory()方法會在服務銷毀的時候調用。
通常情況下,如果我們希望服務一旦啟動就立刻去執行任務,就可以将邏輯寫在onStartCommand() 方法裡。
2.在AndroidMainFest.xml中聲明Service。所有元件都要顯示的聲明
<service android:name=".TestService">
<intent-filter>
<action android:name="com.example.demoapplication.service.TEST_SERVICE"/>
</intent-filter>
</service>
3.UI界面中添加兩個按鈕,ID為stsart_btn,end_btn
MainActivity中的代碼
public class MainActivity extends AppCompatActivity {
private Button start;
private Button end;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start_btn);
end = (Button) findViewById(R.id.end_btn);
//建立啟動Service時的Intent,以及Intent屬性
final Intent intent = new Intent(this,TestService.class); //Android5.0以後版本
/*final Intent intent = new Intent(); Android5.0以前版本*/
intent.setAction("com.example.demoapplication.service.TEST_SERVICE");
//為兩個按鈕設定單擊事件,分别是start和end
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(intent);
}
});
end.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
}
}
使用前台服務
前台服務與普通服務的最大差別在于,它會一直有一個正在運作的圖示在系統的狀态欄中,下拉狀态欄後可以看到更加詳細的内容,非常類似于通知的效果。
@Override
public void onCreate(){
super.onCreate();
Log.d("MyService","onCreate executed");
Intent intent = new Intent(this,MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
startForeground(1,notification);
}
這裡隻修改了onCreate()方法中的代碼,構造一個Notification對象後并沒有使用NotificationManager 來将通知顯示出來,而是調用了startForeground()方法,該方法會将MyService變成一個前台服務,并在系統狀态欄中顯示出來。
Activity和Service通信
他們之間交流的媒介就是Service中的onBind()方法,傳回一個我們自定義的binder對象
基本流程如下:
1. 自定義service中。自定義一個Bind類,然後将需要暴露的方法寫到該類中
2.Service類中,執行個體化這個自定義Binder類,然後重寫onBind()方法,将這個Binder對象傳回!
3.Activity類中執行個體化一個ServiceConnection對象,重寫onServiceConnected()方法,然後 擷取Binder對象,然後調用相關方法即可!
Binder機制初涉:
IBinder是Android給我們提供的一個程序間通信的一個接口,而我們一般是不直接實作這個接口的,而是通過繼承Binder來實作程序間通信,是Android中實作IPC(程序間通信)的一種方式
Binder機制由一系列系統元件構成,Client,server ,Service Manager 和Binder驅動程式
Bind的調用流程如下
1.Client調用某個代理接口中的方法時,代理接口的方法會将Client傳遞的參數打包成Parcel對象
2.然後代理接口把該Parcel對象發送給核心中的Binder Driver
3.然後Server會讀取Binder Driver中的請求資料,假如是發送給自己的,解包Parcel對象,處理并将結果傳回
Binder機制具有可靠性,傳輸性能,安全性
AIDL:
跨程序通信,因為在Android系統中,個個應用程式都運作在自己的程序中,程序之間一般是無法進行資料交換的,而為了實作跨程序,Android給我們提供了上面說的Binder機制,而這個機制使用的接口語言就是AIDL(Android Intereface Definition Language)
AIDL注意事項:
接口名詞需要于aidl檔案名相同
接口和方法前面不要家通路權限修飾符“public,private,protected等,也不能用static final等
AIDL預設支援的類型包括Java基本類型,String,List,Map,CharSqquence,除此之外的其他類型都需要import聲明,對于使用自定義類型作為參數或者傳回值,自定義類型需要實作Parcelable接口,
自定義類型和AIDL生成的其他接口類型在aidl描述檔案中,應該顯示import,即便在該類和定義的包在同一個包中