Activity
創(chuàng)建:自定義類繼承Activity ?重寫 onCreate 方法
注冊(cè):需要在 AndroidManifest.xml 中注冊(cè) Activity
跳轉(zhuǎn):
顯示意圖跳轉(zhuǎn):(一般打開自己的Activity)
創(chuàng)建兩個(gè)類 為FirstActivity 和 SecondActivity 并在清單中聲明 不用配置意圖過濾器
label 為應(yīng)用名字 icon 為圖標(biāo) ?application 中的label 應(yīng)用界面中應(yīng)用名字 icon應(yīng)用設(shè)置界面的圖標(biāo)
通過Intent 帶參構(gòu)造函數(shù) Intent intent = new Intent(this,SecondActivity.class)
若打開其他應(yīng)用的 需要 new Intent(); intent.setClassName("包名","全類名") 并在清單文件中聲明 exported為 true
Intent 可以攜帶八種基本數(shù)據(jù)類型:boolean byte char short int float double long String 以及他們的數(shù)組形式
隱式意圖跳轉(zhuǎn):(一般讓其他應(yīng)用打開自己的Activity)
將第二個(gè)Activity在清單文件中 注冊(cè) 設(shè)置 意圖過濾器 intent-filter action"域名倒寫" ?category 配置為category.DEFAULT 系統(tǒng)默認(rèn)
Intent intent = new Intent();
intent.setAction(必須和清單文件中的action一樣);
intent.setDate(Uri.parse("itheima"+xxx))(與清單文件data scheme 內(nèi)容相同)
媒體類型 mimeType"父類型/子類型" intent.setType("父類型/子類型") 若既有data也有type 要intent.setDataAndType(data,type)
或者 intent.setAction(Intent.ACTION_CALL) intent.setDate(Uri.parse("tel:"+110);設(shè)置一個(gè)動(dòng)作 攜帶數(shù)據(jù)
startActivity(intent);
生命周期:
foreground 前臺(tái)狀態(tài) ?執(zhí)行onResume(刷新數(shù)據(jù))后 onstart()
paused 暫停狀態(tài) ? ? ?若有透明應(yīng)用覆蓋或者有對(duì)話框應(yīng)用 覆蓋的時(shí)候onPause 恢復(fù)的時(shí)候onResume
stopped 停止?fàn)顟B(tài) ? ? onStop(停止刷新界面) 不可見而且不可以操作 按home鍵之后
simple 銷毀狀態(tài)onDestroy(釋放資源)
onCreate
界面的初始化 setcontentView ?findviewbyid
數(shù)據(jù)的初始化 文件/數(shù)據(jù)庫/網(wǎng)絡(luò)/其它的組件/sp
開啟其它的組件(開啟服務(wù),注冊(cè)廣播接收者)
動(dòng)態(tài)注冊(cè)廣播接收者(onCreate注冊(cè) onDestroy注銷 onstart注冊(cè)的onStop注銷 onResume注冊(cè) onPause注銷)
onstart
onResume 刷新界面
onPause ? ?停止刷新界面
onStop
onDestroy 釋放資源 數(shù)據(jù)庫的鏈接 cursor sqlitedatabase bind的服務(wù) 廣播接收者注銷 退出線程
onRestart
創(chuàng)建 onCreate onstart onResume 按返回鍵后 onPause onStop onDestroy
按Home鍵 onPause onStop按home鍵返回 onRestart onstart onResume
startActivityForResult(intent,requestCode); (開啟另外一個(gè)Activity)
onActivityResult(int requestCode, int resultCode, Intent data);
setResult(resultCode, intent data); finish(); (返回?cái)?shù)據(jù)的activity)
屏幕旋轉(zhuǎn)時(shí)生命周期:
onPause onStop onDestroy onCreate onstart onResum
1.默認(rèn):Activity會(huì)銷毀 屏幕旋轉(zhuǎn)后會(huì)創(chuàng)建新的Activity
2.寫死屏幕方向 ?在清單文件中screenOrientation landscape 水平 portrait 豎直
3.configChanges orientation|screenSize 隨著方向改變 不會(huì)銷毀生命周期
重寫onConfigurationChanged 屏幕旋轉(zhuǎn)生命周期方法 處理相關(guān)業(yè)務(wù)邏輯
Activity任務(wù)棧(啟動(dòng)模式):
standard 默認(rèn)情況 只要調(diào)用startActivity就會(huì)創(chuàng)建新的實(shí)例
singleTop 棧頂只有一個(gè)實(shí)例 如果當(dāng)前的activity在任務(wù)棧的棧頂那么 不會(huì)創(chuàng)建新的實(shí)例 除此之外 不會(huì)影響實(shí)例的創(chuàng)建
(一系列調(diào)用的最后一個(gè)頁面 為了避免在這個(gè)頁面上再創(chuàng)建新的實(shí)例可以配置為singleTop)
singleTask 一個(gè)任務(wù)棧中只有一個(gè)實(shí)例 如果這個(gè)activity在棧頂 再次調(diào)用startactivity不會(huì)創(chuàng)建新的 實(shí)例 如果不在棧頂 并且實(shí)例存在
會(huì)把活著的實(shí)例上面的所有activity銷毀 把這個(gè)對(duì)象露出來 (應(yīng)用 的主界面可以配置為singleTask)
singleInstance 獨(dú)占一個(gè)任務(wù)棧 這個(gè)任務(wù)棧中只有一個(gè)實(shí)例 而且整個(gè)手機(jī)只有一個(gè)實(shí)例(慎用 打電 話的界面可以配置為singleInstance)
fragment
1.fragment入門
①創(chuàng)建一個(gè)java類 繼承Fragment重寫oncreateView方法
fragment 也會(huì)對(duì)應(yīng)一個(gè)布局文件 ?這個(gè)布局文件可以通過傳入的LayoutInflater加載到界面上 作為oncreateview的返回值
②在布局文件中聲明相應(yīng)的fragment節(jié)點(diǎn)
注意在聲明fragment節(jié)點(diǎn)時(shí) ?fragment首字母小寫 ?name 必須制定 內(nèi)容是要顯示的Fragment的全類名
2.動(dòng)態(tài)替換fragment(常用)
1.創(chuàng)建FirstFramment和second類繼承 重寫 oncreateView 創(chuàng)建布局 更改最小版本為11
在onCreateView 中 inflater.inflate(R.layout.first,null); ?將返回值作為方法的返回值
2.在Activity布局文件中 創(chuàng)建 ViewGroup(LinearLayout)為fragment容器 id為fragment_container
3在activity當(dāng)中 找到控件 獲取getfragmentManager 通過 fragmentManager 開啟事物 fragmentTransaction
4.通過事務(wù)調(diào)用.replace();傳入 android.R.id.content,new First 或者 R.id.fragment_container ?再提交.commit
5.getWindManager.GetDefaultDisplay().getWidth /getHeight 如果寬大于高 是橫屏 加載第二個(gè) 否則加載第一個(gè)
3.兼容低版本的寫法(classMainActivityextendsFragmentActivity)
所有的跟fragement相關(guān)的api Fragment FragmentManager v4包中獲取FragmentManager
要使用getSupportFragmentManager 這個(gè)方法在 FragmantActivity中才有
FragmentTransaction 都要使用android.support.v4包中的相關(guān)類
3.fragment的生命周期
oncreate 當(dāng)fragment被創(chuàng)建的時(shí)候 調(diào)用oncreate oncreateView 在這個(gè)方法當(dāng)中加載fragment的布局文件
onpause onStop 處理界面需要顯示的東西 狀態(tài)的保存
ondestory 資源的釋放
4.fragment之間的通信
1.新建LeftF與rigntF 重寫..創(chuàng)建布局文件 在LeftF添加按鈕(調(diào)用方法) 在rightF添加一個(gè)TextView 在主界面中 創(chuàng)建兩個(gè)線性布局 權(quán)重為1 寬度為0 高速為m并指定id
2.編寫 onCreateView中的返回值 在Activity中g(shù)etFramentManageer() 再開啟事務(wù).beginTranssaction 調(diào)用兩次replace .commit
3.(在Activity中 創(chuàng)建按鈕點(diǎn)擊 彈吐司方法(這里不適宜點(diǎn)擊事件的第四種寫法)) 在leftF中 view.find 設(shè)置點(diǎn)擊事件 彈吐司
4.在rightF中 view.find找到text控件 創(chuàng)建修改文字方法 給控件傳文字 ?在Activity中的.replace 中添加 第三個(gè)屬性為標(biāo)簽 ?在leftF中g(shù)etFM.gFBt(標(biāo)簽)得到對(duì)象后 調(diào)用修改文字的方法
Service
特點(diǎn):
Service 在 Android 中是一種長(zhǎng)生命周期的組件,它不實(shí)現(xiàn)任何用戶界面,是一個(gè)沒有界面的 Activity
Service 和其他組件一樣,都是運(yùn)行在主線程中,因此不能用它來做耗時(shí)的操作 如果要執(zhí)行耗時(shí)操作 需要 在里邊開一個(gè)子線程 new Thread(){}.start();
進(jìn)程特點(diǎn): 哪個(gè)進(jìn)程被關(guān)閉是由安卓系統(tǒng)衡量對(duì)用戶相對(duì)的重要程度,更容易殺死看不到界面的進(jìn)程,試圖維持每個(gè)進(jìn)程盡可能的活著,有重要性層級(jí)結(jié)構(gòu).
Foreground process 前臺(tái)進(jìn)程 有Activity正在與用戶交互 service在執(zhí)行生命周期方法 廣播接收者在執(zhí)行onreceiver 優(yōu)先級(jí)最高
visible preocess 可視進(jìn)程 有一個(gè)Activity處于可見但不可操作的狀態(tài) 比如有個(gè)透明應(yīng)用蓋在上面 處于onPause狀態(tài)
Service preocess 服務(wù)進(jìn)程 后臺(tái)運(yùn)行著用startService開啟的服務(wù) 沒有組件屬于前兩種情況
Background process 后臺(tái)進(jìn)程 有Activity 處于onStop但是沒有銷毀 沒有其他組件屬于前三種情況 后來進(jìn)程比較多
哪個(gè)先殺死 用LRU算法 最近使用的最后殺 最少使用最先殺
Empty process 空進(jìn)程
開啟方式:
startService:
startService(Intent) 通過這種方式開啟的服務(wù) 執(zhí)行的聲明周期方法: 第一次調(diào)用startService的時(shí)候 onCreate()->onStartCommand
再次調(diào)用startService ->onstartCommand
想停止用startservice開啟的服務(wù) stopService(intent); stopService 執(zhí)行之后 service會(huì)走 onDestroy()方法 執(zhí)行之后service銷毀 再次調(diào)用stopService沒有反應(yīng)
如果在activity中通過startService方法開啟一個(gè)服務(wù) 當(dāng)activity退出的時(shí)候service不會(huì)銷毀 依然在后 臺(tái)運(yùn)行
只有手動(dòng)調(diào)用stopService 或者在應(yīng)用管理器中關(guān)閉service 服務(wù)才會(huì)銷毀
通過startservice可以提高應(yīng)用的優(yōu)先級(jí)
bindService:(可以調(diào)用接口中的方法)
① bindService ?unbindService
② bindservice之后 生命周期 ?onCreate->onBind 多次調(diào)用bindService onBind只會(huì)執(zhí)行一次
③ activity退出的時(shí)候 必須解除跟service的綁定 ?在ondestroy 的時(shí)候調(diào)用 unbindService
④ unbindService多次調(diào)用會(huì)拋異常 只能調(diào)用一次
⑤ bindservice的時(shí)候傳入第二個(gè)參數(shù) 是ServiceConnection ?只有當(dāng) onBind方法返回不為空的時(shí)候 才會(huì)調(diào)用 onServiceConnected
可以將返回值 service 強(qiáng)轉(zhuǎn)為 MyBinder 類型(這個(gè)類是自己寫的 是 onBind的返回值類) 通過這個(gè)對(duì)象可以調(diào)用接口中的方法
AIDL:
讓其它應(yīng)用可以調(diào)用當(dāng)前應(yīng)用service中的方法
RPC remote procedure call 遠(yuǎn)程過程調(diào)用 ?AIDL 解決就是rpc的問題
IPC inter process communication 進(jìn)程間通信 每一個(gè)android應(yīng)用都運(yùn)行在獨(dú)立的進(jìn)程中 所以 應(yīng)用之間的通信就是進(jìn)程間通信
Activity intent BroadCastReceiver 通過onReceive方法 可以處理其他應(yīng)用發(fā)來的廣播 通過Intent 攜帶數(shù)據(jù)
AIDL實(shí)現(xiàn)的過程 :
提供遠(yuǎn)程服務(wù)方法的應(yīng)用 :
① 創(chuàng)建一個(gè)Service 重寫onBind方法 在onBinder中返回一個(gè)Binder對(duì)象 需要遠(yuǎn)程調(diào)用的放發(fā)放到 這個(gè)Binder對(duì)象中
②在清單文件中聲明對(duì)應(yīng)的service 需要添加一個(gè)intent-filter 可以通過隱式意圖調(diào)用service
③ 創(chuàng)建一個(gè)接口 需要暴露給其它應(yīng)用調(diào)用的方法都聲明在這個(gè)接口中
④把接口文件的擴(kuò)展名修改為 .aidl 需要注意 aidl文件不支持public 關(guān)鍵字
⑤修改service的代碼 讓MyBinder繼承Stub
遠(yuǎn)程調(diào)用服務(wù)的應(yīng)用
①用過隱式意圖以及bindService方式 開啟遠(yuǎn)程的服務(wù)
② 創(chuàng)建ServiceConnection的實(shí)現(xiàn)類
③在當(dāng)前應(yīng)用中創(chuàng)建一個(gè)目錄 目錄結(jié)構(gòu)跟提供遠(yuǎn)程服務(wù)的應(yīng)用aidl所在目錄結(jié)構(gòu)保持一致, 把a(bǔ)idl文 件copy過來 如果沒有問題 會(huì)在gen目錄下生成一個(gè) Iservice.java文件 包名跟aidl文件的包名一致
④在onserviceConnected方法中 通過?把當(dāng)前的Ibinder對(duì)象轉(zhuǎn)化成遠(yuǎn)程服務(wù)中的接口類型 最終通過這個(gè)對(duì)象實(shí)現(xiàn)調(diào)用遠(yuǎn)程方法
LRU 剛用過的最后回收 最早用過的最先回收
BroadcastRecevier
特點(diǎn):一對(duì)多 單向傳遞消息 不需要在清單文件中注冊(cè)(動(dòng)態(tài)注冊(cè))
開發(fā)過程:
①寫一個(gè)類繼承BroadcastReceiver
②重寫onReceive方法
③清單文件注冊(cè)(有的時(shí)候不能這么搞,需要通過代碼動(dòng)態(tài)注冊(cè)) 動(dòng)態(tài)的要求控件活著 才能接收到廣播
④可選 有的廣播接收者需要權(quán)限 如果需要權(quán)限還得在清單文件中聲明權(quán)限
有序廣播和無序廣播的區(qū)別:
有序廣播可以被中斷 ?有序廣播的內(nèi)容可以被修改 ?abordBroadCast(); 如果調(diào)用這個(gè)方法之后 廣播 中斷了說明是有序廣播
接收有序廣播的時(shí)候 聲明priority可以確定接收等級(jí) 范圍是0-1000
publicvoidsend(Viewv){
Intentintent=newIntent();
intent.setAction("com.it.sendrice");
//收到廣播時(shí)需要的權(quán)限
StringreceiverPermission=null;
//作為最終的廣播接受者
BroadcastReceiverresultReceiver=newFinalReceiver();
//最終的廣播接收者 傳null在主線程處理
Handlerscheduler=null;
//數(shù)據(jù)
StringinitialData="皇帝發(fā)放賑災(zāi)糧 每人一百斤";
sendOrderedBroadcast(intent,receiverPermission,resultReceiver,scheduler,Activity.RESULT_OK,initialData,null);
}
無序廣播不能被中斷 ?無序廣播內(nèi)容不可以修改 ? ? abordBroadCast(); 如果調(diào)用之后報(bào)紅色日志
publicvoidsendbroadcast(Viewv){
Intentintent=newIntent();
intent.setAction("com.it.broadcast");? //接收廣播程序中注冊(cè)的action與這個(gè)相同
intent.putExtra("key","hello");
sendBroadcast(intent);
}
廣播攜帶的數(shù)據(jù)類型:Boolean ? ? Bundle ? ? byte ? ? char ? ?CharSequce ? double ? ? float ? ? int ? ? long ? ?short ? ?string ? Serializable ? ?Parcelable 和其數(shù)組
動(dòng)態(tài)注冊(cè)廣播接收者:通過在activity 或者 service中調(diào)用 registerReceiver方法 注冊(cè)廣播接收者
BroadcastReceiverreceiver=newScreenLightRecriver();//這個(gè)類為自己創(chuàng)建的
//意圖過濾器
IntentFilterfilter=newIntentFilter();
//意圖過濾器添加ACTION
filter.addAction("android.intent.action.SCREEN_OFF");
filter.addAction("android.intent.action.SCREEN_ON");
//動(dòng)態(tài)注冊(cè)一個(gè)廣播
registerReceiver(receiver,filter);
動(dòng)態(tài)注冊(cè)的廣播接收者:只有調(diào)用了注冊(cè)的方法之后才能夠收到廣播 靜態(tài)注冊(cè)廣播接受者 在清單文件中聲明一個(gè)receiver節(jié)點(diǎn)
除了一些特殊的廣播接收者必須通過 動(dòng)態(tài)方式注冊(cè) 只要在清單文件中聲明了對(duì)應(yīng)的receiver 不管應(yīng)用是否在運(yùn)行都可以收到廣播
動(dòng)態(tài)注冊(cè)的廣播接收者通過當(dāng)前Activity銷毀的時(shí)候需要注銷掉
contentprovider/ contentresolver
內(nèi)容提供者,內(nèi)容解析者
意義:跨應(yīng)用提供數(shù)據(jù) 讓其他應(yīng)用訪問本應(yīng)用數(shù)據(jù)庫中的內(nèi)容
實(shí)現(xiàn)步驟:
① 創(chuàng)建一個(gè)類 繼承ContentProvider 重寫里面方法
② 在清單文件中注冊(cè)相應(yīng)provider ?必須指定authorities 屬性 還要添加一個(gè)屬性 exported = true
③ 在provider中處理uri匹配相關(guān)內(nèi)容
創(chuàng)建URI匹配器 在provider 中搞靜態(tài)代碼塊 在static代碼塊中添加 uri匹配的規(guī)則
根據(jù)業(yè)務(wù)邏輯 在不同的數(shù)據(jù)庫操作方法中 處理uri匹配的流程
④ 其他應(yīng)用訪問contentprovider方法
獲得contentresolver內(nèi)容解析者對(duì)象 getContentResolver
通過contentresolver調(diào)用 增刪改查 方法訪問contentprovider
需要注意 uri 要以content://開頭 ?具體的路徑 要跟contentprovider中 定義的uri匹配規(guī)則匹配上
contentObserver內(nèi)容觀察者:
在數(shù)據(jù)內(nèi)容發(fā)生改變的地方通過contentResolver發(fā)送數(shù)據(jù)變化的通知 notifyChange
在需要接受變化的地方 注冊(cè)一個(gè)內(nèi)容觀察者(可以在同一個(gè)應(yīng)用中 也可以是在不同的應(yīng)用中)
①寫一個(gè)類繼承ContentObserver 重寫onChange方法
②通過contentResolver 調(diào)用registerObserver方法注冊(cè)內(nèi)容觀察者
resolver.registerContentObserver(uri, false, new MyObserver(new Handler()) );
//第一個(gè)參數(shù) uri 把內(nèi)容觀察者注冊(cè)到這個(gè)uri上 如果有通知 說明這個(gè)uri對(duì)應(yīng)的 內(nèi)容發(fā)生改變 內(nèi)容觀察者就會(huì)收到通知
//第二個(gè)參數(shù) 路徑匹配的規(guī)則 如果傳入true 路徑前部分匹配上就可以收到通知 如 果傳false只有整個(gè)路徑都匹配上才能收到通知
//第三個(gè)參數(shù) 內(nèi)容觀察者
文件的存儲(chǔ)
SharedPrefenrences
可以保存的數(shù)據(jù)類型比較少 所以 用sp來保存一些簡(jiǎn)單的配置信息boolean string int long float Set
①獲取sp的實(shí)例 getSharedPreferences("文件名",Mode_private);
②讀內(nèi)容 getXXXX(key,默認(rèn)值); 獲取 SharedPreferences的Editor edit(); editor.putXXXX(key,value); commit();提交 只有調(diào)用了這個(gè)方法 保存的內(nèi)容才會(huì)存到本地
保存位置為包名文件下 一個(gè)文件 保存格式為xml格式
上下文獲取(context)
上下文 描述了當(dāng)前應(yīng)用的環(huán)境
是一個(gè)接口 可以通過上下文訪問到跟當(dāng)前應(yīng)用相關(guān)的資源 資源包括系統(tǒng)的資源(getsystemservice
獲取系統(tǒng)的服務(wù) getwallpaper 獲取壁紙) 也包括應(yīng)用的私有的資源 ?getAssets 獲取assets目錄下的內(nèi)容
getResource() 獲取res目錄對(duì)應(yīng)的api 也可以做應(yīng)用級(jí)別的調(diào)用 開啟一個(gè)activity startActivity ?開啟服務(wù) startService
getFileDir 獲取與應(yīng)用相關(guān)的私有路徑getAbsolutePath()返回抽象路徑名的絕對(duì)路徑名字符串
getPackageManags 獲取應(yīng)用包管理器 getPackageName獲取應(yīng)用包名
//通過上下文獲取應(yīng)用相關(guān)的私有路徑 不要用寫死路徑的方式
//File file = new File(context.getFilesDir().getAbsolutePath()+"/info.txt");FileOutputStream fos = new FileOutputStream(file);
可以通過這行取代上邊兩行 FileOutputStream fos = context.openFileOutput("info2.txt", Context.MODE_PRIVATE);
//通過上下文的api 獲取到data/data/包名/files目錄下對(duì)應(yīng)文件的 輸入流
FileInputStream fis = context.openFileInput("info2.txt");
sd卡
API=Environment環(huán)境 getExternalStprageState 獲取外部存儲(chǔ)器的狀態(tài) MEDIA_MOUNTED 存在并且可讀寫
getExternalStorageDirectory 獲取sD卡的路徑
通過這個(gè)api就可以在存儲(chǔ)的時(shí)候 Environment.getExternalStorageDirectory(),"info2.txt"
數(shù)據(jù)庫
第一步: 創(chuàng)建一個(gè)類繼承 SQLiteOpenHelper ?并實(shí)現(xiàn)父類的構(gòu)造
第二步 ?從寫onCreate 方法 和onUpgrade 方法
第三步 ?在Activity中 創(chuàng)建MySQLOpenHelper對(duì)象( 注意 !!!! 至此并沒有創(chuàng)建數(shù)據(jù)庫)
第四部 ?調(diào)用 MySQLOpenHelper的getReadableDatabase或getWriteableDatabase方法獲 取SQLiteDataBase對(duì)象
增加 刪除 改變 使用 execSQL
查詢使用 rawQuery 得到curor 后遍歷
curor相關(guān)方法 moveToNext() 移動(dòng)到下一行 ? ?getCount() 返回查詢到的結(jié)果一共有多少行
getColumnCount()返回一條結(jié)果中有多少列
getString(index), getInt(index) 根據(jù)列序號(hào)返回相應(yīng)記錄(序號(hào)從0開始)
或者 ? 使用封裝好的api ? ? ①insert方法 ? ? ? ? ? ? ? ?②delete方法 ? ? ? ? ? ? ? ?③update方法 ? ? ? ? ? ? ? ?④query方法
訪問網(wǎng)絡(luò)
獲取&提交數(shù)據(jù)
servlet 是運(yùn)行在 Web 服務(wù)器中的小型 Java 程序。servlet 通常通過 HTTP(超文本傳輸 協(xié)議)接收和響應(yīng)來自 Web 客戶端的請(qǐng)求。
①創(chuàng)建一個(gè)類 繼承HttpServlet ②重寫兩個(gè)方法 doGet ?doPost 這兩個(gè)方法都接受相同的參數(shù)
http協(xié)議
HTTP,HyperText Transfer Protocol
超文本傳輸協(xié)議 目前使用的版本 1.1 ?每次鏈接之后可以保持鏈接不斷 ?直到所有數(shù)據(jù)加載完畢之后 再斷開鏈接
之前老版本 1.0 每次連接之后 必須斷開鏈接 內(nèi)容沒請(qǐng)求完 下次請(qǐng)求還需要?jiǎng)?chuàng)建新的tcp鏈接
http 請(qǐng)求 比如 在瀏覽器中輸入地址 回車 向服務(wù)端請(qǐng)求數(shù)據(jù) 這個(gè)操作就是一個(gè)http請(qǐng)求
響應(yīng) 服務(wù)端給瀏覽器返回?cái)?shù)據(jù)就是http響應(yīng)
請(qǐng)求方式
常用的有兩種 ?put head trace delete
get ? ? ? ①url后面 url和具體的參數(shù)用? 不同的提交參數(shù)之間 &隔開 key=value
②get方式提交所有的參數(shù)都在地址欄中顯示 沒有post安全
③ 瀏覽器對(duì)地址欄接受參數(shù)的長(zhǎng)度有限制 所以get方式不能提交大量數(shù)據(jù) (2k~8k) get方式提交參數(shù)的長(zhǎng) 度<2k 的
post ? ?① 參數(shù)的提交是放到請(qǐng)求體中
② 比get方式更安全
③ 提交參數(shù)的長(zhǎng)度不受限制 ?文件上傳這樣的操作一定要使用post
Handler原理
Handler ?Message ?MessageQueue ?Looper
①Looper 輪詢器 通過Looper去消息隊(duì)列取消息 當(dāng)主線程創(chuàng)建的時(shí)候 就會(huì)創(chuàng)建一個(gè)looper looper在new的時(shí)候 會(huì)創(chuàng)建一個(gè)MessageQueue 所以 一個(gè)線程對(duì)應(yīng)一個(gè)Looper一個(gè)Looper對(duì)應(yīng)一個(gè)MessageQueueLooper 創(chuàng)建之后 必須調(diào)用loop方法 loop方法中 有一個(gè)死循環(huán) 這個(gè)死循環(huán)會(huì)不斷去消息隊(duì)列里取 消息 取出消息之后 就會(huì)調(diào)用 handler的handlemessage方法處理消息
②MessageQueue 通過消息隊(duì)列 把消息進(jìn)行排序 排序的依據(jù)就是消息要執(zhí)行的時(shí)間
③Handler 用來發(fā)送消息 sendMessage->sendMessageAtTime(Message, long uptimeMillis) 第一個(gè)參數(shù) 要發(fā)送的消息 第二個(gè)參數(shù) 消息要執(zhí)行的而時(shí)間 ?這個(gè)時(shí)間就是消息在消息隊(duì)列中排序的依據(jù)sendMessage 最終會(huì)調(diào)用MessageQueue 的enqueueMessage方法 把消息放到消息隊(duì)列進(jìn)行排序 ? ? ?handler 處理消息 handlerMessage
需要記憶的 刻骨銘心的 ?聯(lián)網(wǎng)必須開線程 ?子線程不能更新UIANR 應(yīng)用沒有響應(yīng)
(① handler ?② runOnUIThread())
聯(lián)網(wǎng)① 需要權(quán)限 android.permission.INTERNET
② 用到的基類 HttpURLConnection ?URL url= new URL(String);
url.openConnection();
HttpURLConnection .setRequestMethod()設(shè)置請(qǐng)求方法
setConnectTimeOut 設(shè)置超時(shí)時(shí)間
getResponseCode 獲取響應(yīng)碼
getInputStream 獲取返回的輸入流
handler ?Message msg = Message.obtain(); 獲取消息
msg.obj 通過這個(gè)屬性攜帶數(shù)據(jù)
msg.what 通過這個(gè)int變量區(qū)分不同消息
handler.sendMessage(Message)
handler.sendEmptyMessage(int what); 發(fā)送空消息 runOnUIThread(Runnable );
Bitmap bm =BitmapFactory.decodestream(inputstream) ?從流解析一張圖片
BitmapFactory.decodefile(String path) 從路徑解析圖片
ImageView.setImageBitmap(Bitmap bm ) 給imageview設(shè)置圖片
使用httpurlconnection 把數(shù)據(jù)提交到服務(wù)器
get方式提交 跟直接獲取數(shù)據(jù)不提交參數(shù)的時(shí)候 區(qū)別很小 唯一有不同的地方是 參數(shù)要拼接到URL的后面 拼接的時(shí)候需要注意 如果有中文的參數(shù) 需要進(jìn)行URL編碼 URLencoder.encode();
post方式提交 需要設(shè)置請(qǐng)求頭 Content-Type Content-Length 請(qǐng)求的參數(shù)是通過請(qǐng)求體以流的方式提交到服務(wù)端的 打開輸出流 setDoOutput(true) 獲取輸出流 ?getOutputStream();
需要注意 請(qǐng)求的參數(shù)中如果包含中文內(nèi)容也需要進(jìn)行URL編碼
以httpclient方式把數(shù)據(jù)提交到服務(wù)器
①獲取HttpClient 接口 ?找到實(shí)現(xiàn)類 Default ?Simple ? Basic Base 找到 無參構(gòu)造函數(shù) DefaultHttpClient();
②通過請(qǐng)求獲取響應(yīng) ? execute(HttpRequest);->httpresponse
③HttpRequest也是接口 發(fā)現(xiàn)根據(jù)不同的請(qǐng)求方式有對(duì)應(yīng)的實(shí)現(xiàn)類 HttpGet HttpPost
多線程下載
①多下程下載的好處 可以突破服務(wù)端對(duì)單一線程的速度限制
②多線程下載的原理 2.1服務(wù)端得支持多線程讀取數(shù)據(jù) 可以通過Range頭來通知服務(wù)端 當(dāng)前線程請(qǐng)求的數(shù)據(jù)范圍 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
range頭成功返回?cái)?shù)據(jù) 響應(yīng)碼是206 2.2客戶端通過RandomAccessFile 進(jìn)行多線程寫 寫的時(shí)候調(diào)用RandomAccessFile的seek方法
不 同線程移動(dòng)到不同的位置開始寫文件
①聯(lián)網(wǎng) 獲取要下載文件的大小 ②本地創(chuàng)建一個(gè)相同大小的文件 ③根據(jù)線程的數(shù)量和要下載文件的大小計(jì)算每個(gè)線程要下載的數(shù)據(jù)范圍
④開啟線程 聯(lián)網(wǎng) 拿著計(jì)算好的數(shù)據(jù)范圍到服務(wù)端請(qǐng)求數(shù)據(jù) ?響應(yīng)碼206 ⑤通過RandomAccessFile保存文件 調(diào)用seek方法
UI相關(guān)
listview
ListView 入門
這個(gè)控件是用垂直滾動(dòng)的列表展示條目.由ListAdapter(列表適配器)提供條目.
1.在xml文件中添加ListView控件 添加id 找到控件 設(shè)置一個(gè)適配器 寫一個(gè)類 實(shí)現(xiàn)BaseAdapter(接口的抽象類) 重寫4個(gè)方法
2.getView方法 通過這個(gè)方法創(chuàng)建條目的界面 決定了每一個(gè)條目長(zhǎng)成什么樣子 新建TextView 設(shè)置數(shù)據(jù)
ListView 優(yōu)化
1.getCount 方法決定要展示多少條目; convertview 為空表示目前沒有view對(duì)象被移出屏幕
2.判斷convertview== null 創(chuàng)建TextView對(duì)象展示條目 ?如果不為空 tv_text=()covertView ;
fastScrollEnabled 允許快速滾動(dòng)
ListView展示數(shù)據(jù)的原理(MVC)
view 視圖 ? ?controller 控制器 ? model 數(shù)據(jù)模型
ListView ? ? baseAdapter ? ? ? ? Arraylist
TextView 文本展示
EditText 文本輸入框
Button 按鈕
Imageview 圖片
ImageButton 圖片按鈕
RadioGroup ?與單選按鈕有關(guān)
CheckBox ?勾選框booleanchecked?=cb.isChecked()if(checked)?{}else{} 可根據(jù)勾選狀態(tài)做響應(yīng)的操作
progressbar ?進(jìn)度條style="@android:style/Widget.ProgressBar.Horizontal"可設(shè)置為橫向的
seekbar可拖動(dòng)的進(jìn)度條
AlertDialog 對(duì)話框
progressDialog ?進(jìn)度條
AutocompleteTextView ?自動(dòng)補(bǔ)全的TextView
Menu 菜單
Surfaceview 視頻
VideoView 視頻
多媒體
圖片處理
通過Matrix 矩陣rotate 旋轉(zhuǎn)Translate 平移?Scale縮放
每次set后圖片都會(huì)恢復(fù) 如果想在set基礎(chǔ)上操作 需用post方法
大圖加載:
通過比較圖片分辨率和屏幕分辨率 如果圖片分辨率大 需要進(jìn)行壓縮,壓縮的大小就是 圖片分辨率和屏幕分辨率寬度和高度的比例
如果inJustDecodeBounds設(shè)置為true那么再調(diào)用BitmapFactory.decodeXXX方法的時(shí)候只會(huì)讀取圖片的寬度和高度
//取寬度和高度計(jì)算出來的比例的最大值 作為壓縮的大小
option.inSampleSize = Math.max(Math.round(heightIndex), Math.round(widthIndex));
option.inJustDecodeBounds = false;
創(chuàng)建圖片副本:
//通過BitmapFactory加載圖片
//創(chuàng)建出一張跟原圖一樣大的空白圖片 這個(gè)圖片可以修改 ?mutable
Bitmap bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//通過canvas畫圖canvas.drawBitmap(bitmap, matrix, paint);
音頻視頻的播放
MediaPlayer播放:
new MediaPlayer();
player.setDataSource("mnt/sdcard/xpg.mp3");//設(shè)置數(shù)據(jù)源
player.prepare();player.start();
Surfaceview播放
VideoView 播放
Vitamio播放動(dòng)畫:導(dǎo)入開源項(xiàng)目
動(dòng)畫
Animation and Graphics Overview 通過安卓提供的api讓ui動(dòng)起來 也可以畫 2d或者3D動(dòng)畫 3.0之后加入了屬性動(dòng)畫
幀動(dòng)畫 Drawable Animation
補(bǔ)間動(dòng)畫view Animation
使用xml方式定義補(bǔ)間動(dòng)畫 ①在res目錄下創(chuàng)建一個(gè)anim目錄 在里面聲明xml文件
②在代碼中使用animationUtils.loadAnimation加載需要注意 補(bǔ)間動(dòng)畫/view動(dòng)畫 不會(huì)改變控件的位置
屬性動(dòng)畫property Animation (android 3.0之后加入)
屬性動(dòng)畫 確實(shí)修改了控件的屬性 如果使用的屬性動(dòng)畫 看到控件位置改變了 實(shí)際的位置也改變了