【黑馬程序員】軟件項目管理
(一)咱們現在是在學習階段,慢慢的接觸項目這個概念。那么項目是什么?
一個項目的組成,還有期生命周期,項目經理如何管理項目,項目如何分解,每個階段的產出,都是什么,我們在進入工作前,可以提前了解一下,就能大概體會項目經理的工作內容,也能體諒一個項目所帶來的壓力。
首先軟件項目管理,什么是項目?什么是軟件項目? 項目是唯一的,臨時的,即在一定的時間內完成。
具體定義:項目是為了創造一個唯一的產品或提供一個唯一的服務而進行的臨時性的努力。項目的特征: 項目有明確的目標
項目之間的活動具有相關性 限定的周期 有獨特性
資源成本的約束性(預算)
項目的不確定性(需求變更、人員變動。。)
說了那么多項目的特征,那么軟件項目又有什么特別的嗎?
軟件項目是一個邏輯實體,相互之間的作用更強,變更會隨時發生,以及更深的漸進聯系。正是由于軟件項目的變更性很強,所以為了確保軟件項目的成功,提出了要對軟件項目進行管理。
項目管理的定義:項目管理是一系列的伴隨著項目的進行而進行的、目的是為了確保項目能達到期望結果的一系列管理行為。
軟件項目管理與傳統的項目管理之間的比較區別:軟件項目的管理除了要對軟件項目深入了解,掌握項目管理的知識,還要有相應的經驗和技巧
了解了項目管理,現在就來看看必不可少的項目管理知識體系(pmbok)
十大管理:范圍管理、時間管理、費用管理、質量管理、人員管理、溝通管理、風險管理、采購管理、集成管理、利益相關者管理 采鑒自傳統項目管理,過程的管理如流水線生產生產的產品都是一樣的,不同的過程造就不同的產品,那么對于軟件項目管理來說,不同的過程一樣產生不同的產品,不同的過程造就的產品質量也就不同,那么管理好了過程產品質量也就會相應提升。這里給出過程管理的定義:過程管理就是對過程進行管理,目的是讓過程能夠被共享、復用,并得到持續的改進。
軟件過程管理的過程組:初始、計劃、控制、執行、結束
于是我們得到軟件項目管理的過程:初始、計劃、執行控制、結束
從項目初始開始:包括項目確立和生存期
項目確立分成 項目立項、項目招投標、項目授權
項目立項:確定項目的目標、時間、資源、資金,關鍵在于得到項目發起人的認可 一個軟件項目的立項開始于軟件項目的啟動,只有立項了的需求才會得到滿足
項目招投標:在確認決策為購買時,便要啟動項目招投標,過程為甲方招標書定義、乙方項目分析、招標與競爭、合同簽署
黑馬程序員成都中心 編著
項目授權:項目章程(project charter)表示項目存在
項目授權后項目管理便要開始履行職責 包括:開發計劃、組織實施、項目控制
案例總結:某公司發出甲方招標書,然后一些科技公司開始對該招標書進行項目分析,然后向甲方公司發送投標書,由甲方進行選擇,擬定合同并簽訂,中標后乙方收到項目授權書,項目便正式成立
項目成立后便要選擇相應的完成項目的策略,即選擇項目生存期模型 軟件項目生存周期
定義:描述了開發的主要階段、定義每個階段完成的過程和活動、確認每個階段完成的輸入和輸出
傳統生存期模型:預期設計開發的過程
瀑布模型:單向,嚴格要求項目的步驟,即需求分析、設計、編碼實施、測試、維護,管理方便但是不能滿足需求變更
V模型:瀑布模型的變種,仍舊為單向執行,對項目需求、方案要求非常明確,以及對安全有特殊要求的項目。
原型:對變化的需求可以進行相應的應對,在需求分析后構造原型,然后對原型進行評估,再構造原型再評估,直到確定項目需求,然后設計最終系統,最后實現。增量模型:需求基本明確,可能發生變化,對于市場和用戶需要逐步了解,需要一步步實施。以增量的方式一步步完善系統功能。
漸進式模型:漸進式前進、階段性提交,優點是階段性提交一個可運行的產品,關鍵的功能更早出現,早起預警問題,避免缺陷蔓延,階段性完成可以降低完成估計錯誤。敏捷生存期模型(agile development):自適應的過程 敏捷宣言:
個體和交互勝過過程和工具
可以工作的軟件勝過面面俱到的文檔 客戶合作勝過合同談判 響應變化勝過遵循計劃
軟件需求管理
軟件需求定義:用戶對軟件功能和性能的要求
軟件需求管理過程:需求獲取、需求分析、需求規格編寫、需求驗證、需求變更
變更管理:確定需求變更控制過程、確立變更控制委員會(SCCB)、進行需求變更影響分析、跟蹤所有受需求變更影響的工作產品、建立需求基準版本和需求控制版本文檔、維護需求變更的歷史記錄、跟蹤每項需求的狀態、衡量需求穩定性 軟件建模的基本方法:
原型方法:需求分析、原型開發、原型評價
結構化分析法 :面向數據流的方法、自頂向下的分析方法、根據軟件內部數據傳遞、交換的關系進行分析的,包括的技術有數據流圖、數據字典、系統流程圖
面向對象的用例分析:基于面向對象的情景分析方法、從用戶角度出發考慮的功能需求、用例是系統向用戶提供一個有價值的結果的某項功能 uml需求視圖:用例視圖、順序圖、狀態圖、活動圖
功能列表法:將需求各功能以列表的形式列出,可以配合用例分析方法,對用例進行展開描述。
黑馬程序員成都中心 編著
敏捷方法:對需求采用漸進明晰的方法進行描述
在敏捷方法中,用戶需求被描述成一個個story card,有以下基本格式:as a ,i want ,so that 判斷一個user story 是否是一個好的story的標準
軟件項目任務分解
任務分解是項目管理的基礎
任務分解過程定義:將一個項目分解為更多的工作細目或子項目,使項目變得更小、更易管理、更易操作
WBS任務分解結構:wbs是對項目由粗到細的分解過程,面向交付成果的,wbs組織并定義了整個項目范圍
工作包是wbs最低層次的可交付成果 工作包應當由唯一主體負責 任務分解方法:
類比:有相同或相似的周期的項目,可采用類比的方法 模板參照:進行項目分解的時候,有些項目可以參照模板 自上而下:對項目整體有比較詳細的了解
自下而上:任務沒有非常詳細的邏輯關系,想到什么寫什么,然后按一定邏輯生成 任務分解步驟:
確認并分解項目的組成要素(WBS編號)確定分解標準 確定分解是否詳細
確定項目交付成果(可以編制WBS字典)驗證分解的正確性
檢驗分解結果的標準:
最底層的要素是否是實現目標的充分必要條件 最底層要素是否有重復的 每個要素是否清晰完整定義
最底層要素是否有定義清晰的責任人 是否可以進行成本估算和進度安排
--暫時就說到這里,這里的一切標準都是由各種辦法來進行的。跟我們所接觸的其他工作都不一樣。希望對大家以后的工作有一定的幫助。
黑馬程序員成都中心 編著
01、什么是3G 02、android系統簡介 03、android背景介紹 04、android的framewor簡介 05、兩種虛擬機的比較 06、sdk的下載以及簡介 07、創建android模擬器 08、ddms簡介
09、platform-tools的簡介及常見adb指令
10、android項目的目錄結構
11、android下apk安裝的過程
12、常見的adb指令介紹
13、創建模擬器遇到的常見錯誤
14、電話撥號器
15、點擊事件的四種寫法
16、短信發送器
17、相對布局&單位介紹
18、現形布局&布局的組合
19、表格布局&絕對布局 20、幀布局
21、測試相關概念
22、android下junit測試框架配置
23、logcat簡介
24、保存文件到手機內存
25、android下文件訪問的權限
26、保存文件到SD卡中
27、分析setting源代碼獲取SD卡大小
28、_sharePreference入門
29、xml文件的序列化 30、采用pull解析xml文件
31、采用斷電調試的方法觀察pull解析的的流程
32、android下創建一個sqllite數據庫
33、sql語句實現數據庫的增刪改查
34、系統api實現數據庫的增刪改查&Sqlite3工具的使用
35、數據庫的事物
36、listView入門
37、采用layoutInflater打氣筒創建一個view對象
38、采用數據適配器ArryAdapter
39、常用數據適配器simpleAdapter 40、數據適配器總結
41、內容提供者簡介
42、內容提供者的實現
43、短信的備份
44、插入一條記錄到系統短信應用
45、內容觀察者
46、獲取系統的聯系人信息
47、保存聯系人到系統通訊錄
48、讀取聯系人的一個小細節
49、網絡圖片查看器
50、anr產生的原理&如何避免
51、android消息機制入門
52、網絡html查看器
53、字符亂碼問題的處理
54、采用get方式提交數據到服務器
55、采用post方式提交數據到服務器
56、提交數據到服務器中文亂碼問題的處理
57、采用httpclient提交數據到服務器
58、異步http框架簡介&實現原理
59、異步http框架提交數據到服務器 60、上傳文件到服務器
61、smartimageview&常見開源代碼 62、多線程下載的原理 63、多線程斷點下載的原理
64、多線程java代碼移植到android 65、多線程下載文本頁面的更新 66、顯示意圖激活另一個activity 67、隱式意圖激活另一個activity 68、隱式意圖的配置
69、隱式意圖和顯示意圖的使用場景 70、在不同activity之間數據傳遞 71、activity的聲明周期 72、activity的啟動模式
73、activity橫豎屏切換的聲明周期 74、開啟新的activity獲取他的返回值 75、請求碼和結果碼的作用 76、利用廣播實現ip撥號 77、短信竊聽器
78、自定義廣播時間&發送自定義廣播&廣播接受者優先級 79、采用服務執行長期后臺操作 80、采用服務竊聽電話&服務的聲明周期 81、android進程優先級&為什么使用服務 82、綁定方式開啟服務&調用服務的方法 83、服務的聲明周期(混合開啟 84、采用aidl綁定遠程服務
85、代碼注冊廣播接受者&利用廣播調用服務的辦法 86、加載大圖片到內存 87、獲取圖片exif信息 88、從gallery獲取圖片 89、圖片畫畫板 90、扒開美女衣服 91、圖片的縮放 92、圖片的旋轉
93、圖片的平移&鏡面&倒影效果 94、圖片的合成 95、圖片的顏色處理 96、多媒體播放api簡介 97、人臉識別
98、mediaplayer的生命周期 99、soundpoo簡介
100、sufaceview的生命周期 101、播放在線視頻
102、視頻播放器進度的處理 103、調用系統照相機拍照和錄像 104、采用camera拍照 105、常見對話框 106、notification入門 107、菜單
108、android下的樣式 109、android下的主題
110、代碼編寫ui 111、html創建ui 112、幀動畫
113、代碼創建創建的tween動畫 114、xml文件定義動畫 115、傳感器簡介 116、117、殺死進程 118、apk的安裝 119、應用程序的反編譯 120、動態創建fragment 121、用fragment創建一個選項卡 122、fragment的向下兼容性 123、fragment的生命周期 124、fragment之間的通訊 125、應用程序國際化
04、android的framewor簡介
Wap:wait and play Wireless Makeup Language(WML)精簡的html語言 Applications:android自帶的基本上層應用 Aplication framework:應用程序框架 Librarics: Linux lernel:
05、兩種虛擬機的比較
編譯后文件格式:
jvm:.java->.class->.jar dalvik vm:.java->.dex->.odex 基于的架構:
jvm:基于棧的架構
dalvik vm:基于寄存器的架構
Cpu直接訪問寄存器因此dalvik虛擬機的效率比jvm高
06、sdk的下載以及簡介
->獲取sdk工具包(sdk:standard develope kits)->ADT(android develop tools,實際上是eclipse的插件)SDK具體內容
Android 4.2.2(API16)
->SDK Plateform:開發時使用到的jar包->Samples for sdk:
->ARM EABI V7a System Image:模擬器運行時的鏡像->Intel n86 Aton System:模擬器運行時的鏡像->MIPS System Image:模擬器運行時的鏡像->google APIs:google提供的jar包,可以直接使用google提供的一些API->source for android SDK:SDK全部的源代碼 Extrals:
->tools:開發的工具
->support library:實現高版本的android向下的兼容->google Admed Ads SDK:gongle提供的廣告插件->Analyties App Irackiong SDK:應用的用戶分析->cloud message:云消息
->gongle play service:收費服務
->google USB Driver:真實的設備驅動
開發時:基于4.0,兼容2.2、2.3.3
07、創建android模擬器
avd:android virture developer VGA:480*640(電視的標準分辨率)QVGA:240*320(四分之一)HVGA:320*480(一半)WVGA:480*800(width)FWVGA:480*854(更寬)
08、ddms簡介
ddms:模擬器不支持中文,因此發送中文會顯示不出來
09、platform-tools的簡介及常見adb指令
Android調試橋:內部實現就是socket讓兩個系統之間實現數據交互
->reset adb:模擬器找不到時候可以重啟->adb device:列出所有的連接的設備->adb kill-server:殺死adb調試橋->adb start-server 啟動adb調試橋 dx.bat:將.class文件打包
10、android項目的目錄結構
一:SDK的目錄結構
->Samples->Api demo:根據API demo(模擬器上面可以看見)的效果可以在sample中看見
相應的代碼
->Source:jar包所有的sdk源代碼都在這個文件夾里->SystemImage:系統鏡像
->temp:下載更新臨時存儲的文件夾,一般是空的->tools:emulater.ext 不同版本的模擬器
二:New Android Application->theme:留給以后作為擴展,現在并沒有太大的作用->target SDK:一般選擇高版本,因為高版本對下兼容
->mark project as a library:一般不選擇,意思是將這個項目提供一個
jar包供別人使用 三:文件夾目錄
.setting:設置目錄
assets:資產目錄,存放一些文件,這些文件會被原封不動打包到應用程序的 apk中
bin:
gen:自動生成的目錄
->builderConfig.java:生成的配置信息->R.java: Android 4.1.2->android.jar開發環境,jar包
可以在properties中修改,jar包就是SDK
011、Android下apk的安裝過程
一、Android安裝過程分析:
->setContentView:甚至view的對象,把里面的xml文件加載到
->在project中選擇build automaticly會自動把文件生成字節碼文件,.class $代表的class文件生成的是內部類->dex.bat文件會把.class文件生成.dex文件
->apk壓縮文件解壓內部內容
->META-INF: 應用程序的簽名
eclipse的調試簽名文件
->res:資源文件
->classes.dex:class文件
->resources.arsc:資源ID映射
->android軟件安裝的過程:
->拷貝xxx.apk帶/data/app/xxx-1.apk->在/data/data目錄下創建一個文件夾,文件夾名稱當前應用程序的報名
012、常見adb指令
前提:
->設備連接上電腦而且驅動安裝正常,如果安裝不正常的話,會有黃色的問號顯示;
->設備上打開USB調試;
指令:
->adb device(如果啟動發現這個程序沒有安裝會自動安裝)->adb kill-server->adb start-server->adb uninstall <包名>->adb-s emulator-5554 install c:usersadministratorhello.apk 如果有多個設備的話,如果不指定安裝的是哪個設備程序會報錯->adb push haha.prop /sdcard/haha.txt 將文件移到
(360管家,豌豆莢之類的軟件他們也是用的adb指令,倘若電腦上裝這些軟件的話,會因為兩個adb指令搶端口號而掛掉)(adb版本之間兼容不是很好,經常報錯可以考慮下版本的問題)->adb shell:遠程連接到了android的linux終端
ls:顯示文件夾
ps:顯示正在運行的程序 ping:網絡連通性
013、創建模擬器遇到的常見錯誤
->路徑最好不要有中文:
->應用安裝不上,或者安裝模擬器的時候開啟一個新的模擬器:
可能是模擬器的資源被占用,模擬器在運行的時候其實占用著硬盤上面的一個文件,這個文件位于工作空間.android/avd/iphone.avd 里面會有鏡像文件,當一個模擬器開啟起來了,就給你創建一個文件夾.knock的文件夾,代表著這個模擬器被鎖定了,如果把模擬器關掉,就沒有程序占據這幾個鏡像資源了,那么這幾個程序就會被自動刪除。通常情況下不會出問題,開啟時候創建文件,關閉時關閉文件,但是當電腦出現不正常狀態時:比如藍屏,停電關機時候這些資源還沒來得及刪除,模擬器就關閉了,因此開啟時這些資源仍在,程序默認模擬器被占用,因此會重新開啟一個模擬器。
->模擬器沒有信號:
模擬器用socket橋接在電腦上
終結解決方案是給電腦連上網,分配一個IP->常見命令操作:
14、電話撥號器
->新建文件
->界面設置:文本框、點擊按鈕
-> :一旦獲得焦點,會立刻彈出,輸入文本的軟鍵盤->ctrl+x刪除->ctrl+1提示
->設置點擊事件:找到空間,然后設置點擊事件,再點擊事件里面獲得了另外一
個空間的數據,激活一個intent->獲得權限:清單文件中添加uses permision
15、點擊事件的四種寫法
->電話撥號器的優化:
每次撥打電話都會執行的操作是:查找控件,然后找到控件的文本,撥打電
話。其實每次撥打電話文本控件已經創建好了沒有必要每次查找按鈕之后再 查詢控件。
package cn.wqrt.mobile;
import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_number;@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =(Button)findViewById(R.id.bt_dial);et_number =(EditText)findViewById(R.id.et_number);button.setOnClickListener(new MyListener());}
private class MyListener implementsandroid.view.View.OnClickListener{
@Override
public void onClick(View arg0){
String number = et_number.getText().toString().trim();//去除回車和空格
if(TextUtils.isEmpty(number)){
Toast.makeText(MainActivity.this, “號碼不能為空”, Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent();
intent.setAction(intent.ACTION_CALL);
intent.setData(Uri.parse(“tel:”+number));
startActivity(intent);
}
}
@Override public boolean onCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;} }
->
1、點擊事件的四種寫法:
->給按鈕注冊點擊事件:創建一個內部類定義點擊事件。具體代碼見上
button.setOnClickListener(new MyListener());
->
2、采用匿名內部類創建點擊事件:
button.setOnClickListener(new OnClickListener()){
package cn.wqrt.mobile;
import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_number;@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =(Button)findViewById(R.id.bt_dial);et_number =(EditText)findViewById(R.id.et_number);button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0){
// TODO 自動生成的方法存根
callPhone();
}
});}
@Override public boolean onCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
private void callPhone(){
String number = et_number.getText().toString().trim();//去除回車和空格
if(TextUtils.isEmpty(number)){
Toast.makeText(MainActivity.this, “號碼不能為空”, Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent();
intent.setAction(intent.ACTION_CALL);
intent.setData(Uri.parse(“tel:”+number));
startActivity(intent);} } }
->
3、如果有很多的按鈕點擊事件,建議用這種方式:讓Activity實現點擊 事件的接口,每個按鈕點擊事件都設置成this,讓該類實現 OnClickListener然后進行判斷。package cn.wqrt.mobile;
import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText et_number;@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =(Button)findViewById(R.id.bt_dial);et_number =(EditText)findViewById(R.id.et_number);button.setOnClickListener(this);}
@Override public boolean onCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
private void callPhone(){
String number = et_number.getText().toString().trim();//去除回車和空格
if(TextUtils.isEmpty(number)){
Toast.makeText(MainActivity.this, “號碼不能為空”, Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent();
intent.setAction(intent.ACTION_CALL);
intent.setData(Uri.parse(“tel:”+number));
startActivity(intent);}
@Override public void onClick(View v){
// TODO 自動生成的方法存根
switch(v.getId()){
case R.id.bt_dial:
callPhone();
break;
} } }->
4、在布局文件中綁定一個點擊的方法,如果點擊按鈕就會調用這個方法,通
過反射技術試圖調用這個方法
布局文件中設置: package cn.wqrt.mobile;
import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_number;@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =(Button)findViewById(R.id.bt_dial);et_number =(EditText)findViewById(R.id.et_number);
}
@Override public boolean onCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
public void dialButtonClick(View v){ callPhone();}
private void callPhone(){
String number = et_number.getText().toString().trim();//去除回車和空格
if(TextUtils.isEmpty(number)){
Toast.makeText(MainActivity.this, “號碼不能為空”, Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse(“tel:”+number));
startActivity(intent);} }
16、短信發送器
->界面的設計:兩個large Text,一個Button
android:textColor 設置字體顏色
android:singleLine=“true” 設置是否是單行
android:lines=“5” 設置行數
windows下面的顏色是GBR,而android下需要輸入的格式確實
RGB,所以需要轉換
adb默認設置time out為5秒->內容設計:按鈕-文本->判斷->發送
導包的時候千萬別導到gsm包,否則會顯示過時;
發送沒有歷史記錄 package com.example.sms;
import java.util.ArrayList;
import android.app.Activity;import android.os.Bundle;import android.telephony.SmsManager;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText et_number;private EditText et_content;
@Override protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button =(Button)findViewById(R.id.bt_send);
et_number =(EditText)findViewById(R.id.et_number);
et_content =(EditText)findViewById(R.id.et_content);
button.setOnClickListener(this);}
@Override public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);
return true;}
@Override public void onClick(View v){
// TODO 自動生成的方法存根
switch(v.getId()){
case R.id.bt_send:
String number = et_number.getText().toString().trim();
String content = et_content.getText().toString().trim();
if(TextUtils.isEmpty(number)||TextUtils.isEmpty(content)){
Toast.makeText(this, “號碼或者內容不能為空”,Toast.LENGTH_SHORT).show();
return;
}else{
SmsManager smsManager = SmsManager.getDefault();
ArrayList contents = smsManager.divideMessage(content);
for(String str:contents){
smsManager.sendTextMessage(number, null, str, null, null);
}
}
} } }
17、相對布局&單位介紹
->布局說明:
->同級控件:
android:layout_toRightOf=“" android:layout_toLeftOf=”“ android:layout_below=”' android:layout_above=“" android:layout_maginBottom=”“
->相對父控件:
android:ayout_centerInParent=”“ android: layout_centerHorizontal=”“ android:layout_centerVertical=”“ android:layout_alignParentBottom=”“ android:layout_alignParentRight=”“->對齊方式:
->文本顏色:#00000000~#ff000000(argb)文字的透明度->單位介紹:
dp也就是dip:device independent pixels(設備獨立像素),是一種與密度無關的像素單位,在每英寸160點的屏幕上,1dp = 1px。不同設備有不同的顯示效果,這個和設備硬件有關,一般我們為了支持WVGA、HVGA和QVGA 推薦使用這個,不依賴像素
1.2.android:layout_height=”wrap_content“
3.android:text=”@string/clickme“
4.android:layout_marginTop=”20dp“ />
scaled pixels(刻度像素).主要用于定義字體的大小,而從來不再layout上使用
o
1.2.android:layout_height=”wrap_content“
3.android:textSize=”20sp“ />
px:pixels(像素).不同設備顯示效果相同,一般我們HVGA代表320x480像素,這個用的比較多 總結:dp也就是dip。這個和sp基本類似。如果設置表示長度、高度等屬性時可以使用dp或sp。但如果設置字體,需要使用sp。dp是與密度無關,sp除了與密度無關外,還與scale無關。如果屏幕密度為160,這時dp和sp和px是一樣的。1dp=1sp=1px,但如果使用px作單位,如果屏幕大小不變(假設還是3.2寸),而屏幕密度變成了320。那么原來TextView的寬度設成160px,在密度為320的3.2寸屏幕里看要比在密度為160的3.2寸屏幕上看短了一半。但如果設置成160dp或160sp的話。系統會自動將width屬性值設置成320px的。也就是160 * 320 / 160。其中320 / 160可稱為密度比例因子。也就是說,如果使用dp和sp,系統會根據屏幕密度的變化自動進行轉換.附:px 和 dp 互轉換
1.package com.hujl.util;import android.content.Context;
public class DensityUtil {
/**
* 根據手機的分辨率從 dp 的單位轉成為 px(像素)
*/
public static int dip2px(Context context, float dpValue){
final float scale = context.getResources().getDisplayMetrics().density;
return(int)(dpValue * scale + 0.5f);
}
/**
* 根據手機的分辨率從 px(像素)的單位轉成為 dp
*/
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return(int)(pxValue / scale + 0.5f);
} }
18、線性布局&布局的組合
->線性布局:
->線:就是view對象
android:layout_height=”1px“
android:background=”#ff0000“ > />
通常采用相對布局和絕對布局聯合使用的方式。
19、表格布局&絕對布局
->表格布局:渲染權重
->絕對布局:對控件位置任意擺放,需要計算不同屏幕中的位置,因為android
軟件的屏幕大小實在太多,所以并不方便,不推薦使用。
20、幀布局
>幀布局:
->類似于網頁布局中的div
android:visibility:”“ //顯示是否可見,播放器最喜歡使用幀布局,暫停播放的時候,會在上面顯示一個按鈕
21、測試相關概念
->根據測試測試是否知道程序的源代碼:
->黑盒測試:不知道源代碼,只關心程序執行的過程和程序的結果,一個資
深的黑盒程序人員工資很高,因為他們和正常用戶的使用思維
不一樣
->白盒測試:根據源代碼寫測試方法或者測試用例->根據測試的粒子度:
->方法測試:function test->單元測試:unit test->集成測試:intergration test->根據測試的次數:
->冒煙測試:smoke test 反復不停的執行,反復不停的使用(android猴子
來測試)
->adb shell
->monkey
->monkey 5000(點擊五千次)
->壓力測試:pressure test同時抗住多人的請求->
22、android下junit測試框架配置
23、logcat簡介
->日志信息級別:
Verbose:提醒 黑色
Debug: 調試 藍色
Info: 信息 綠色
Warn: 警告 橙色
Error: 錯誤 紅色
24、保存文件到手機內存
->數據存儲與訪問
->文件
->SharePreferences(參數)
->SQLite數據庫
->內容提供者(Content Provide)
->網絡
->LinearLayout一定要設置水平還是垂直->文件保存:
->javase中通過創建文件對象,但是在androi中這種存放方式會失敗,因
為會默認為存儲在當前目錄文件下
->android中創建一個包:com.itheima.login.service
創建一個類:LoginService.java
異常的處理:如果是返回值是boolean,那么拋出處理都可以,但是如果返回值是void,那么只能拋出了
->context:上下文就是一個類,這個類提供了很多方便的API,可以得到應用程
序的環境
環境包名 安裝路徑 文件的路徑 資源的路徑 資產的路徑
放到緩存文件夾里面:getCacheDir();->getAssest();->getResource();->getFilesDir();/data/data/包名
->getCacheDir();/data/data/包名/cache
->MainActivity.java package com.example.login;
import java.util.Map;
import android.app.Activity;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.widget.CheckBox;import android.widget.EditText;import android.widget.Toast;
import com.example.login.service.LoginService;
public class MainActivity extends Activity {
private EditText et_number;private EditText et_passwd;private CheckBox cb_remPass;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//首先要把頁面加載進來然后才有控件的獲取
et_number =(EditText)findViewById(R.id.et_number);
et_passwd =(EditText)findViewById(R.id.et_passwd);
cb_remPass =(CheckBox)findViewById(R.id.cb_remPass);
Map map = LoginService.getSavaUserInfo(this);
if(map!= null){
et_number.setText((CharSequence)map.get(”username“));
et_passwd.setText((CharSequence)map.get(”passwd“));
} }
@Override public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);
return true;} public void login(View v){
String number = et_number.getText().toString().trim();
String passwd = et_passwd.getText().toString().trim();
if(TextUtils.isEmpty(number)||TextUtils.isEmpty(passwd)){
Toast.makeText(this, ”登錄名或者密碼不能為空“, Toast.LENGTH_SHORT).show();
return;
}else{
if(cb_remPass.isChecked()){
//如果選擇了保存用戶密碼,那么就保存用戶密碼
boolean results = LoginService.saveuserInfo(this,number, passwd);
if(results){
Toast.makeText(this, ”保存用戶信息成功“, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, ”保存用戶信息失敗“, Toast.LENGTH_SHORT).show();
}
}
//登陸發送消息到服務器,服務器驗證是否正確
if(”zhangsan“.equals(number)&&”123456“.equals(passwd)){
Toast.makeText(this, ”登陸成功“, Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, ”登錄失敗,用戶名或者密碼不正確“, Toast.LENGTH_LONG).show();
}
} } }
->LoginService.java package com.example.login.service;
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;
import android.content.Context;/* * 保存用戶名密碼的的業務方法 */ public class LoginService { public static boolean saveuserInfo(Context context,String userName,String passWord){//沒有使用任何類的方法,推薦使用靜態方法
//File file = new File(”/data/data/com.example.login/info.txt“);
File file = new File(context.getFilesDir(),”info.txt“);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write((userName+”##“+passWord).getBytes());
fos.close();
return true;
} catch(FileNotFoundException e){
// TODO 自動生成的 catch 塊
e.printStackTrace();
return false;
} catch(IOException e){
// TODO 自動生成的 catch 塊
e.printStackTrace();
return false;
}
} /* * 獲取保存到的數據
*/ public static Map getSavaUserInfo(Context context){
File file = new File(context.getFilesDir(),”info.txt“);
Map map = new HashMap();;
try {
FileInputStream fis = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
String str = bufferedReader.readLine();
String[] infos = str.split(”##“);
map.put(”username“, infos[0]);
map.put(”passwd“, infos[1]);
} catch(FileNotFoundException e){
// TODO 自動生成的 catch 塊
e.printStackTrace();
return null;
} catch(IOException e){
// TODO 自動生成的 catch 塊
e.printStackTrace();
return null;
}
return map;} }
->activity_main.xml
android:id=”@+id/bt_login“
android:onClick=”login“
android:layout_width=”100dp“
android:layout_height=”wrap_content“
android:layout_alignParentRight=”true“
android:text=”@string/bt_login“
/>
android:id=”@+id/cb_remPass“
android:layout_width=”wrap_content“
android:layout_height=”wrap_content“
android:layout_alignParentLeft=”true“
android:layout_alignParentTop=”true“
android:layout_alignBottom=”@id/bt_login“
android:text=”@string/remPass“
android:checked=”true“ />
25、android下文件訪問的權限
->private、readable、writeable、public
26、保存文件到SD卡中
->存儲空間:
->手機的內部存儲空間:小硬盤 /data/data->外部存儲空間:SD卡 路徑/mnt/sdcard 可以簡寫成/sdcard/
需要權限WRITE_EXTER_STORAGE
操作SD卡必須要權限
->保存數據到SD卡只需要把路徑改為SD卡,讀不需要權限,否則需要權限
在4.0以前的版本讀SD卡不需要權限,但是在4.0以
后讀寫SD卡可以設置SD卡保護,讀就需要權限 READ_EXTER_STORAGE->判斷是否存在SD卡:Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
->為了保證程序的兼容性,有些SD卡可能路徑會改變,因此系統提供了獲取SD 卡的路徑的方法
Environment.getExternalStorageDirectory()
27、分析setting源代碼獲取SD卡大小
->source的源代碼是SDK的源代碼,是jar里面的源代碼->導入通用的文件項目eclipse要求必須要有setting文件->ctrl+h搜索文件夾
package com.example.sdsize;
import java.io.File;
import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.os.StatFs;import android.text.format.Formatter;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;
public class MainActivity extends Activity {
private TextView tv_SDsize;protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button =(Button)findViewById(R.id.bt_find);tv_SDsize =(TextView)findViewById(R.id.tv_SDSize);
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0){
// TODO 自動生成的方法存根
StringBuilder memorySizeInfo = new StringBuilder();
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
memorySizeInfo.append(getExternalSize());
}else{
Toast.makeText(MainActivity.this,”無內存卡“, Toast.LENGTH_SHORT).show();
}
memorySizeInfo.append(getRomSpaceInfo());
tv_SDsize.setText(memorySizeInfo.toString());
}
});} /* * 獲取SD卡的存儲信息 */ public String getExternalSize(){
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
long availableBlocks = stat.getAvailableBlocks();
long totalSize = blockSize*totalBlocks;
long availSize = blockSize*availableBlocks;
String totalStr = Formatter.formatFileSize(this, totalSize);
String availStr = Formatter.formatFileSize(this, availSize);
String ExternalSize = ”SD總存儲空間:“+ totalStr + ”可使用的空間:“ + availStr;
return ExternalSize;} /* * 獲取可用的內部存儲 */ public String getRomSpaceInfo(){
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long internalblockSize = stat.getBlockSize();
long internalblockcounts = stat.getBlockCount();
long internaltotalSize = internalblockSize*internalblockcounts;
String totalStr = Formatter.formatFileSize(this, internaltotalSize);
String RomSpaceInfo = ”可用的內存“+ totalStr;
} return RomSpaceInfo;} @Override public boolean onCreateOptionsMenu(Menu menu){ // Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
28、sharedPreferences入門
->數據存儲的API:用##分割用戶名和密碼的缺陷,真實存
儲的話必須要把##轉移成其他字符,sharePreferences
(共享參數)提供了一種方便存儲數據的方式。
->在data目錄下創建了一個xml文件,根節點是map,其實是以map集合來存
儲的用戶名和密碼的對特殊字符進行了轉義
package loginsharedPreference.service;
import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;
/* * 保存用戶名密碼的的業務方法 */ public class LoginService { public static void SavaUserInfo(Context context,String username,String passwd){
//拿到上下文之后,有個方法叫getSharedPreferences
SharedPreferences sharedPreferences = context.getSharedPreferences(”config“, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();//得到sharedPreferences的編輯器
}
editor.putString(”username“,username);editor.putString(”passwd“,passwd);//類似于數據庫的事物
editor.commit();//當前方法不會存在異常,所以設置為void } package loginsharedPreference;
import java.util.Map;
import loginsharedPreference.service.LoginService;import android.app.Activity;import android.content.SharedPreferences;import android.os.Bundle;import android.text.TextUtils;import android.view.Menu;import android.view.View;import android.widget.CheckBox;import android.widget.EditText;import android.widget.Toast;
import com.example.login.R;
public class MainActivity extends Activity {
private EditText et_number;private EditText et_passwd;private CheckBox cb_remPass;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//首先要把頁面加載進來然后才有控件的獲取
et_number =(EditText)findViewById(R.id.et_number);
et_passwd =(EditText)findViewById(R.id.et_passwd);
cb_remPass =(CheckBox)findViewById(R.id.cb_remPass);
SharedPreferences sharedPreferences = getSharedPreferences(”config“,MODE_PRIVATE);
String username = sharedPreferences.getString(”username“, ”“);
String passwd = sharedPreferences.getString(”passwd“, ”“);
et_number.setText(username);
et_passwd.setText(passwd);
}
@Override public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);
return true;} public void login(View v){
String number = et_number.getText().toString().trim();
String passwd = et_passwd.getText().toString().trim();
if(TextUtils.isEmpty(number)||TextUtils.isEmpty(passwd)){
Toast.makeText(this, ”登錄名或者密碼不能為空“, Toast.LENGTH_SHORT).show();
return;
}else{
if(cb_remPass.isChecked()){
//如果選擇了保存用戶密碼,那么就保存用戶密碼
LoginService.SavaUserInfo(this,number, passwd);
Toast.makeText(this, ”保存用戶信息成功“, Toast.LENGTH_SHORT).show();
}
//登陸發送消息到服務器,服務器驗證是否正確
if(”zhangsan“.equals(number)&&”123456“.equals(passwd)){
Toast.makeText(this, ”登陸成功“, Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, ”登錄失敗,用戶名或者密碼不正確“, Toast.LENGTH_LONG).show();
}
} } }
29、xml文件的序列化
->一個小異常:如果沒有識別這個設備,重啟的話要記得吧adb殺掉->自己手動添加,這種方式效率低,容易出錯->XmlSerializer:XML序列化生成器
30、采用pull解析xml文件
->用于對象的持久化,將對象寫到硬盤中,需要用的時候再反序列化取出來。
所謂序列化其實就是將程序中的數據(對象)通過某種方式,保存到本地中。然后可以在程序關閉之后還保存程序的某個執行狀態,方便在程序下次
執行的時候通過”反序列化“讀取出來,并且能夠還原數據的類型,從而延續程序退出時的狀態。
一般來說,我們會使用序列化保存一些需要持久化的數據,當然如果這個數據會比較龐大的話,我們就直接使用數據庫了!所以,序列化實際上目前很多領域用的已經不多了,大部分使用 都已被數據庫替代了!
序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。可以對流化后的對象進行讀寫操作,也可將流化后的對象傳輸于網絡之間。序列化是為了解決在對對象流進行讀寫操作時所引發的問題。序列化的實現:將需要被序列化的類實現Serializable接口,該接口沒有需要實現的方法,implements Serializable只是為了標注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStrea
->xml文件的解析方式:
->DOM一次將XML文件加載進內存,生成樹狀結構,在內存中對樹狀結構進
行操作,缺點是消耗內存大,->SAX解析:基于事件的方式,自上而下,事件下去了就不能解析了,優點
是速度快,效率高,缺點是不能倒退;
->android下增加了一種解析xml文件的方式,pull解析,類似于SAX解析,定義了一個指針,指向了文檔的開頭,得到指針,一個tag一個tag的解析下去
->利用類加載器走到文件->創建一個解析器:pullParse0
具體代碼:
(MainActivity.java)package com.example.xml;
import java.util.List;
import org.w3c.dom.Text;
import com.example.xml.domain.WeatherInfo;import com.example.xml.service.WeatherService;
import android.support.v7.app.ActionBarActivity;import android.support.v7.app.ActionBar;import android.support.v4.app.Fragment;import android.app.Activity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.os.Build;
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv =(TextView)findViewById(R.id.tv);
List weatherInfos = WeatherService.getWeatherInfos(MainActivity.class.getClassLoader().getResourceAsStream(”weather.xml“));
StringBuilder sb = new StringBuilder();
for(WeatherInfo info:weatherInfos){
sb.append(info.toString()+”n“);
}
tv.setText(sb.toString());}
@Override public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);
return true;} }
(WeatherInfo.java)/** * */ package com.example.xml.domain;
import android.R.integer;/** * @author yonghen * */ public class WeatherInfo { private int id;private String name;private String wind;private String weather;private String temp;private String pm;/*(non-Javadoc)* @see java.lang.Object#toString()*/ @Override public String toString(){
return ”WeatherInfos [id=“ + id + ”, name=“ + name + ”, wind=“ + wind
+ ”, weather=“ + weather + ”, temp=“ + temp + ”, pm=“ + pm
+ ”]“;}
/** * @param id * @param name * @param wind * @param weather
* @param temp * @param pm */ public WeatherInfo(){ super();} public WeatherInfo(int id, String name, String wind, String weather,String temp, String pm){ super();this.id = id;this.name = name;this.wind = wind;this.weather = weather;this.temp = temp;this.pm = pm;} /** * @return the id */ public int getId(){ return id;} /** * @param id the id to set */ public void setId(int id){ this.id = id;} /** * @return the name */ public String getName(){ return name;} /** * @param name the name to set */ public void setName(String name){ this.name = name;} /** * @return the wind */
public String getWind(){ return wind;} /** * @param wind the wind to set */ public void setWind(String wind){ this.wind = wind;} /** * @return the weather */ public String getWeather(){ return weather;} /** * @param weather the weather to set */ public void setWeather(String weather){ this.weather = weather;} /** * @return the temp */ public String getTemp(){ return temp;} /** * @param temp the temp to set */ public void setTemp(String temp){ this.temp = temp;} /** * @return the pm */ public String getPm(){ return pm;} /** * @param pm the pm to set */ public void setPm(String pm){ this.pm = pm;
}
}
(WeatherService.java)/** * */ package com.example.xml.service;
import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;
import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserException;
import android.R.integer;import android.util.Xml;
import com.example.xml.domain.WeatherInfo;/** * @author yonghen * */ public class WeatherService { public static List getWeatherInfos(InputStream inputStream){
XmlPullParser xmlPullParser = Xml.newPullParser();
WeatherInfo weatherInfo = null;
List weatherInfos = null;
try {
xmlPullParser.setInput(inputStream, ”utf-8“);
int type = xmlPullParser.getEventType();//拿到的是當前的事件類型:
while(type!= xmlPullParser.END_DOCUMENT){
switch(type){
case XmlPullParser.START_TAG:
if(”info“.equals(xmlPullParser.getName())){//解析到全局開始的標簽
weatherInfos = new ArrayList();
}else if(”city“.equals(xmlPullParser.getName())){
weatherInfo = new WeatherInfo();
String idString = xmlPullParser.getAttributeName(0);
weatherInfo.setId(Integer.parseInt(idString));//字符串轉化成整型數據
}else if(”temp“.equals(xmlPullParser.getName())){
String temp = xmlPullParser.nextText();
weatherInfo.setTemp(temp);
}else if(”wind“.equals(xmlPullParser.getName())){
String wind = xmlPullParser.nextText();
weatherInfo.setWind(wind);
}else if(”name“.equals(xmlPullParser.getName())){
String name = xmlPullParser.nextText();
weatherInfo.setName(name);
}else if(”weather“.equals(xmlPullParser.getName())){
String weather = xmlPullParser.nextText();
weatherInfo.setName(weather);
}else if(”pm“.equals(xmlPullParser.getName())){
String pm = xmlPullParser.nextText();
weatherInfo.setPm(pm);
}
break;
case XmlPullParser.END_TAG:
if(”city“.equals(xmlPullParser.getName())){
weatherInfos.add(weatherInfo);
weatherInfo=null;
}
break;
}
type = xmlPullParser.next();
}
} catch(XmlPullParserException e){
// TODO Auto-generated catch block
e.printStackTrace();
} catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
return weatherInfos;} }(Weather.xml)
20/30
5月20日 多云轉晴
南風3-4
上海
200
20/30
5月19日 多云轉晴
南風3-4
上海
200
20/30
5月18日 多云轉晴
南風3-4
上海
200
20/30
5月17日 多云轉晴
南風3-4
上海
200
31、采用斷點調試的方法觀察pull解析的的流程
->現在代碼雙單擊添加斷點
->debug as Android Application->然后打開調試視圖
32、android下創建一個sqllite數據庫
->SQLiteOpenHelper(數據庫大概幫助類):數據庫創建和打開的幫助類->
->PersonSQLiteOpenHelper.java /** * */ package com.example.sqlite;
import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;/** * @author yonghen * */ public class PersonSQLiteHelper extends SQLiteOpenHelper {
/**
* @數據庫的構造方法,用來定義數據庫的名稱,數據庫查詢的結果集,數據庫的版本 */ public PersonSQLiteHelper(Context context){//Context:上下文告訴數據庫存放在什么位置,String name:數據庫名,factory一般為null,設置系統默認的游標工廠,super(context, ”Person.db“, null, 1);
} /* * 數據庫第一次被創建的時候調用的方法,db創建的數據庫 */ @Override public void onCreate(SQLiteDatabase db){
db.execSQL(”create table person id integer primary antoincrement,name varchar(20),number varchar(20)");//底層存儲類型都是String,(20)都是給程序員看的,其實沒有影響
}
/*(non-Javadoc)* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)*/ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ } }
->TestPersonDB.java /** * */ package com.example.sqlite;
import android.database.sqlite.SQLiteAbortException;import android.database.sqlite.SQLiteDatabase;import android.test.AndroidTestCase;/** * @author yonghen * */ public class TestPersonDB extends AndroidTestCase { public void testCreateDB(){ PersonSQLiteHelper personSQLiteHelper = new PersonSQLiteHelper(getContext());//new出來一個對象,實際上數據庫并未被真正的創建,測試框架提供了一個獲取Context的方法
personSQLiteHelper.getWritableDatabase();//數據庫才會被真正的創建出來, } }
33、sql語句實現數據庫的增刪改查
->javaweb:
->加載到jdbc的驅動;//android已經集成在framework->鏈接到數據庫;//只要拿到數據庫的引用
->準備sql語句 增刪改查
->增加:insert into person(name,number)values('zhang','110')->刪除:delete from person where name = 'zhangsan'->修改:update person set number = '119' where name = 'zhangsan'->查找:select * from person->查找具體:select * from person where name = 'zhangsan'
->PersonSQLiteHelper.java /** * */ package com.example.sqlite;
import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;/** * @author yonghen * */ public class PersonSQLiteHelper extends SQLiteOpenHelper {
/** * @數據庫的構造方法,用來定義數據庫的名稱,數據庫查詢的結果集,數據庫的版本
*/ public PersonSQLiteHelper(Context context){//Context:上下文告訴數據庫存放在什么位置,String name:數據庫名,factory一般為null,設置系統默認的游標工廠,
自薦信_XXX_151********
姓名:XXX
電話:151********
郵箱:********n2009@126.com
尊敬的老師:
你好,我叫XXX,今年24歲,就讀于XXXX,XXXX專業,將于2012年畢業。性格稍內向,善于交流,看待事情能夠理性認識,善于思考,有團隊合作精神。在學校的這三年多的時間里,由于專業需要,對計算機接觸較多。在開設的課程中學過C語言、C#、java等編程語言,對編程語言有一定的了解。在接觸java程序語言和J2ME手機游戲開發的學習中,對java產生了強烈的興趣,并對java學習有了一定的基礎。通過“黑馬程序員訓練營”的官網,我了解到了javaee+3G課程體系所包含的知識面廣,是經過對java前景分析和現在就業所需技術要求而制定的,對我們這些即將參加就業、想參加java方面工作的人來說是最好的強心劑。課程安排科學合理,有助于學員深化對java的學習,使學員掌握到真正前沿的技術。我深信,“黑馬程序員訓練營”的講師是java培訓和開發方面最棒的,這也是我鐘情于“黑馬程序訓練營”的原因之一。由于家里生活拮據,不想讓父母操心、給家里增加經濟負擔,是“黑馬程序員”給了我一個機會、給了我一份保證。
作為一名理科生,我有著很強的求知欲,勤奮,有上進心,對于堅信的事情能夠堅持到底。在平時學習過程中,善于獨立思考,遇到問題會嘗試各種方法去解決(網絡、老師、同學都是我的獲得知識的途徑)。平時喜歡看一些和自己專業的書籍,樂于了解一些最前沿的科技和未來的發展趨勢。注重的基礎知識的同時,喜歡探索新知識,在收獲知識的同時也收獲著樂趣。學習是一輩子的事情,也是一件樂事,就算將來學校的生活結束了,學習也永遠不會落下。
我非常期待能成為“黑馬程序員訓練營”的一員,如果這個愿望能實現,我將以最大的熱情投入到“黑馬程序員訓練營”的學習中去,用自己的努力去實現的自身價值,用自己的成績回報“黑馬程序員訓練營”。我堅定工作后的第一件事就是努力工作,用工資償還培訓期間的費用,絕不辜負“黑馬程序員訓練營”對我的信任和老師的培養!請給我一份信任,我將以自己的自己的行動去回報。
擇是我的期望,給我一次機會還你一份驚喜。
非常感激你能在百忙之中翻閱我的自薦信。祝你工作順利,事業蒸蒸日上!
此致
敬禮
自薦人:XXX
2012年02月17號
黑馬程序員自薦信
在當今社會中,需要使用自薦信的場合越來越多,自薦信可以幫助我們更好地提出請求。你還在為寫自薦信而苦惱嗎?以下是小編為大家整理的黑馬程序員自薦信,僅供參考,希望能夠幫助到大家。
尊敬的老師:
您好!
在閱讀過幾十份,甚至上百份的自薦信之后,或許,您已經有了些許疲倦與困意,但還是感謝您打開了我的這封自薦信。對于您來說,或許只是打開了一封信,而對于我來說,您為我開啟了一扇窗,一扇可以看見未來,追逐夢想的的窗戶。
我是趙玉杰,現在就讀于沈陽建筑大學,理學院,信息與計算科學專業,目前大三。說起來,我也和黑馬有點緣分,由于專業的.相近性,我在學校學習了c語言,c++語言,java語言,數據庫(sql),數據結構(c語言版),計算機網絡,操作系統等相關科目,算是有一點基礎,但也僅僅只能是基礎。這個社會需要的不是基礎,而是真才實干。
力,獲得足夠的項目經驗,掌握得心應手的實際操作……就是讓我從眾多畢業生里面脫穎而出的最佳選擇。為了這一目標,我發現了黑馬,一匹讓我很驚訝的黑馬!!
“黑馬程序員”成立于20xx年,20xx年正式上線運營。在短短的3年里,在it培訓行業,“黑馬程序員”不負眾望的成為了一匹業界高度認可的黑馬。在短短的四年時間里,“黑馬程序員”為社會塑造了一大批it相關行業的精英。從黑馬畢業的學員,得到了公司與社會的認可,實現了自己的社會價值,人生目標。在中關村軟件園與csdn的大力支持下,在傳智播客的教學實施下,“黑馬程序員”已經成為了程序員的一種標榜,而能成為“黑馬程序員”的一員,是每一個程序員的愿望,更是一種榮耀。而我更是殷切的希望能夠成為黑馬的一員,讓我脫穎而出,讓我底氣十足。
關于黑馬的“0學費入學”教學理念,也是特別吸引我的一大亮點。據我了解,每一位黑馬學員都必須通過長達2個月的面試流程,在技術,自學能力,性格,壓力,品德等等全方位測試。可以說,黑馬程序員訓練營的所有學員都是精挑細選出來的。我很期待能與這樣的精英一起努力。畢業之后,“工資低于4k,不收任何費用,”只有真正有實力,有責任,有擔當的黑馬才能說的出口。而從黑馬走出的每一個學員,都有能力,有責任,有義務履行我們當初的還款以及相關協議,關于這一點,我堅信不疑。
黑馬程序員基礎測試題
1、已知一個int數組, 編程從數組中獲取最大數.2、編寫一個方法(名字自定,但要符合Java編碼規范),方法內打印一字符串,并在main()方法內調用它。
3、環境變量path和classpath的作用是什么?
系統環境 path 為了更方便應用java 開發工具 將要執行命令的所在路徑給系統、讓系統去尋找 方便執行、必須是可執行文件先找當前路徑再找path 路徑 臨時配置方式 通過set 命令完成、設置查看環境變量的值 在path環境變量的基礎上添加新的目錄 在任意目錄下執行java 執行程序 專門給類文件設置路徑 將class 文件所在目錄 告訴系統,讓系統去尋找 虛擬機先從classpath 尋找
4、UDP協議與TCP協議有什么不同?
5、編寫一個類Person,為Person類定義年齡、姓名兩個屬性,并且定義一個SayHello方法,方法執行時輸出“我是***我的年齡是***”;定義一個Chinese類從Person類繼承。
6、創建一個包含有private的屬性和private方法的類。然后創建一個內部類,它有一個方法可用來修改外部類的屬性,并調用外部類的方法。在外部類的另一個方法中,創建此內部類的對象,并且調用它的方法。
7、用控制臺程序輸出九九乘法表;輸出結果按下圖所示:
1*1=1
1*2=22*2=4
1*3=32*3=63*3=9
.........8、編寫程序拷貝一個文件, 盡量使用效率高的方式.9、編寫HTML注冊表單, 需要字段: 用戶名, 密碼, 確認密碼, 性別(單選), 城市(下拉列表), 興趣愛好(多選), 個人簡介(文本域).10、定義一個學生類, 需要有姓名, 年齡, 考試成績三個成員屬性,創建5個對象, 屬性可為任意值.編程對這5個對象按成績排序,并將結果輸出。(提示,用TreeSet和Comparator實現)