Android工程目錄結構:
« 熟練掌握Android四大元件,常用的布局檔案
Android中4大元件是:ContentProvider、Activity、BroadcastReceiver和Service
一、清單檔案:
1、所有的應用程式必須要有清單檔案
在manifest節點下需要聲明目前應用程式的包名
2、包名:聲明包的名字,必須唯一
如果兩個應用程式的包名和簽名都相同,後安裝的會覆寫先安裝的
3、聲明的程式的元件(4大元件)
其中比較特殊的是廣播接收者,可以不在清單檔案中配置,可以通過代碼進行注冊
4、聲明程式需要的權限:保護使用者的隐私
5、可以控制服務在單獨的程序中的,四大元件都可以配置這個屬性process
在元件節點配置process:
如:android:process=“xxx.ooo.xxx”
比如說:處理圖檔的時候,會很耗記憶體,就需要在單獨的新的程序中,可以減少記憶體溢出的幾率
二、ContentProvider 内容提供者
1、特點
①、可以将應用中的資料對外進行共享;
②、資料通路方式統一,不必針對不同資料類型采取不同的通路政策;
③、内容提供者将資料封裝,隻暴露出我們希望提供給其他程式的資料(這點有點類似Javabeans);
④、内容提供者中資料更改可被監聽;
2、建立:
1.1、定義類繼承ContentProvider, 實作6個抽象方法(ContentResolver對象是解析ContentProvider對象的)
在查詢時,query,傳回的Cursor前不用關閉db,否則customer是空
1.2、清單檔案中的節點下定義節點, 指定name和authorities屬性
因為在應用目錄下,是以可以寫成android.name=” . 類名”,如建立的類是MyProvider,并且在應用目錄下,寫成:android.name=” .MyProvider”,不過不建議這樣寫,因為不明确是什麼應用
在清單檔案中配置的時候,可以指定權限android.readpremission
1.3、内容提供者并不是在應用釋出的時候建立,而是在第一次通路自定義的繼承ContentProvider類的時候才被建立出來
Tips:
其中的authorities是作為目前應用的唯一辨別,雖然可以任意寫,但是需要遵循一定的規範:建議是公司名.providers.表名provider,或者是其他的約定的規範
如:com.itheima.providers.personprovider等
3、通路:
通過Context對象擷取ContentResolver對象
ContentResolver就可以調用增删改查方法了, 方法中都需要傳入一個Uri
Uri的格式: content://authorities/path/id
Tips:Uri代表了要操作的資料
4、監聽内容提供者的資料變化
1)在内容提供者中可以通知其他程式資料發生變化
通過Context的getContentResolver()方法擷取ContentResolver
調用其notifyChange()方法發送資料修改通知,發送到系統的公共記憶體(消息信箱中)
2) 在其他程式中可以通過ContentObserver監聽資料變化
通過Context的getContentResolver()方法擷取ContentResolver
調用其registerContentObserver()方法指定對某個Uri注冊ContentObserver
自定義ContentObserver,重寫onChange()方法擷取資料
5、差別Provider/Resolver/Observer
1)ContentProvider:内容提供者
把一個應用程式的私有資料(如資料庫)資訊暴露給别的應用程式,讓别的應用程式可以通路;
在資料庫中有對應的增删改查的方法,如果要讓别的應用程式通路,需要有一個路徑uri:
通過content:// 路徑對外暴露,uri寫法:content://主機名/表名
2)ContentResolver:内容解析者
根據内容提供者的路徑,對資料進行操作(crud);
3)ContentObserver:内容觀察者
可以了解成android系統包裝好的回調,資料發送變化時,會執行回調中的方法;
ContentResolver發送通知,ContentObserver監聽通知;
當A的資料發生變化的時候,A就會顯示的通知一個内容觀察者,不指定觀察者,就會發消息給一個路徑
三、Activity活動
UI線程雖然叫UI線程,但它并不是隻管繪制界面,UI線程就是主線程,activity是對象,主線程調用activity對象來繪制界面。
因為調用過程中是鎖定的,是以也隻有主線程可以修改UI,所有得名UI線程。
既然是面向對象你就該以對象為核心,線程工作其實就是調用對象,activity之間的切換隻不過就是主線程在調用不通的activity對象而已。
描述:
1)表示使用者互動的一個界面(活動),每一個activity對應一個界面
2)是所有View的容器:button,textview,imageview;我們在界面上看到的都是一個個的view
3)有個ActivityManager的管理服務類,用于維護與管理Activity的啟動與銷毀;
Activity啟動時,會把Activity的引用放入任務棧中
4)一個應用程式可以被别的應用程式的activity開啟
此時,是将此應用程式的引用加入到了開啟的那個activity的任務棧中了
5) activity是運作在自己的程式程序裡面的
在一個應用程式中,可以申請單獨的程序,讓此應用程式中的一個元件在新的程序中運作
6)可以在activity裡面添加permission标簽,調用者必須加入這個權限
與錢打交道的界面,都不允許被其他應用程式随意打開
如果覺得那個activity比較重要,可以在清單檔案中配置,防止别人随意打開,需要配置一個權限
自定義權限:
在清單檔案中配置permission,建立一個新的權限
建立後,就會在清單檔案中生成這個權限了
此時,需要開啟這個界面,就需要使用這個權限
Tips:
*不可使用中文文本,需要使用字元串,抽取出來
聲明之後,會在gen的目錄下,多出來一個檔案:Manifest的檔案,系統也存在一個這樣的檔案
1、建立Activity
1)定義類繼承自Activity類;
2)在清單檔案中Application節點中聲明節點;
<!—啟動時,預設比對 –
2、啟動Activity
通過意圖(Intent)來啟動一個Activity;
1) 顯示啟動:
顯示啟動一般用于自己調用自己的情況(在目前應用找),這樣的啟動方式比較快速,建立Intent後指定包名和類名;
Intent intent = new Intent(this, OtherActivity.class);
startActivity(intent); // 啟動新的Activity
或者:
Intent intent = new Intent();
intent.setClassName(“com.itheima.activity”, “com.itheima.activity.OtherActivity”); // 包名、全類名
startActivity(intent); // 啟動新的Activity
2)隐式啟動:
一般用于調用别人的Activity,建立Intent後指定動作和資料以及類型;
// 電話
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL); // 設定動作
intent.setData(Uri.parse(“tel://123456”)); // 設定資料
// 網頁
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(“http://192.168.1.45:8080/androidWeb”));
// 音頻/視訊,設定type
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(“file:///mnt/sdcard/daqin.mp3”), "audio/"); // 設定資料和資料類型,将啟動音頻播放器(vedio)
3)為隐式啟動配置意圖過濾器:
顯式意圖是指在建立意圖時指定了元件,而隐式意圖則不指定元件,通過動作、類型、資料比對對應的元件;
在清單檔案中定義時需要定義才能被隐式意圖啟動;
中至少配置一個和一個,否則無法被啟動;
Intent對象中設定的action、category、data在必須全部包含Activity才能啟動;
中的、、都可以配置多個,Intent對象中不用全部比對,每樣比對一個即可啟動;
如果一個意圖可以比對多個Activity,Android系統會提示選擇;
3、啟動時傳遞資料
可通過意圖Intent對象實作Activity之間的資料傳遞;使用Intent.putExtra()方法裝入一些資料, 被啟動的Activity可在 onCreate方法中getIntent()擷取;
可傳輸的資料類型: a.基本資料類型(數組), b. String(數組), c. Bundle(Map), d. Serializable(Bean), e.Parcelable(放在記憶體一個共享空間裡);
接收資料:在OtherActivity 的onCreate()方法,通過 getIntent().get 相關的資料的方法來擷取資料;
4、關閉時傳回資料
基本流程:
l 使用startActivityForResult(Intent intent, int requestCode) 方法打開Activity;
l 重寫onActivityResult(int requestCode, int resultCode, Intent data) 方法;
l 新Activity中調用setResult(int resultCode, Intent data) 設定傳回資料之後,關閉Activity就會調用上面的onActivityResult方法;
注意:新的Activity的啟動模式不能設定成 singleTask(如果已建立,會使用以前建立的)與singleInstance(單例,單獨的任務棧),
不能被摧毀(執行不到finish方法),父Activity中的 onActivityResult方法将不會執行;
finish():表示關閉目前Activity,會調用onDestroy方法;
5、生命周期
Activity從建立到銷毀有多種狀态,從一種狀态到另一種狀态時會激發相應的回調方法,這些回調方法包括:oncreate ondestroy onstop onstart onresume onpause
其實這些方法都是兩兩對應的,onCreate建立與onDestroy銷毀;
onStart可見與onStop不可見;onResume可編輯(即焦點)與onPause;
比如說教育應用寶用戶端每次進入某個界面的時候都要看到最新的資料,這個重新整理清單的操作 就放在onStart()的方法裡面.
fillData() 這樣保證每次使用者看到的資料都是最新的.
1)Acitivity三種狀态
a. 運作:activity在最前端運作;
b. 停止:activity不可見,完全被覆寫;
c. 暫停:activity可見,但前端還有其他activity<>,注意:在目前Activitiiy彈出的對話框是Activity的一部分,彈出時,不會執行onPause方法;
2)生命周期相關的方法(都是系統自動調用,都以 on 開頭):
a. onCreate: 建立時調用,或者程式在暫停、停止狀态下被殺死之後重新打開時也會調用;
b. onStart: onCreate之後或者從停止狀态恢複時調用;
c. onResume: onStart之後或者從暫停狀态恢複時調用,從停止狀态恢複時由于調用onStart,也會調用onResume(界面獲得焦點);
d. onPause: 進入暫停、停止狀态,或者銷毀時會調用(界面失去焦點);
e. onStop: 進入停止狀态,或者銷毀時會調用;
f. onDestroy: 銷毀時調用;
g. onRestart: 從stop狀态恢複時調用;
應用啟動時,執行onCreate onStart onResume,退出時執行:onPause onStop onDestroy;
3)生命周期圖解:
6、橫豎屏切換與資訊的儲存恢複
1)切換橫豎屏時,會自動查找layout-port 、layout-land中的布局檔案,預設情況下,切換時,将執行摧毀onPause onStop onDestroy,再重置加載新的布局onCreate onStart onResume;切換時如果要儲存資料, 可以重寫: onSaveInstanceState();恢複資料時, 重寫: onRestoreInstanceState();
2)固定橫屏或豎屏: android:screenOrientation=“landscape”
3)橫豎屏切換, 不摧毀界面(程式繼續執行) android:configChanges=“orientation|keyboardHidden|screenSize” 隻會執行onConfigurationChanged方法
儲存資訊狀态的相關方法:
a. onSaveInstanceState: 在Activity被動的摧毀或停止的時候調用(如橫豎屏切換,來電),用于儲存運作資料,可以将資料存在在Bundle中;
b. onRestoreInstanceState:該方法在Activity被重新繪制的時候調用,例如改變螢幕方向,onSavedInstanceState可為onSaveInstanceState儲存的資料