成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

所有Android 開(kāi)發(fā)者都要知道的開(kāi)發(fā)常識(shí)

移動(dòng)開(kāi)發(fā)
可見(jiàn)現(xiàn)代軟件開(kāi)發(fā)對(duì)開(kāi)發(fā)者的綜合素質(zhì)(這并不是facebook所講的全棧工程師)越來(lái)越高,自稱為碼農(nóng)或者程序猿顯然是不合理的,因?yàn)檫@個(gè)過(guò)程是腦力勞動(dòng)和體力腦動(dòng)并存,稱呼自己為工程師顯得更為合理。

[[155312]]

軟件開(kāi)發(fā)流程

一個(gè)完整的軟件開(kāi)發(fā)流程離不開(kāi)策劃、交互、視覺(jué)、軟件、測(cè)試、維護(hù)和運(yùn)營(yíng)這七個(gè)環(huán)節(jié),這七個(gè)環(huán)節(jié)并不是孤立的,它們是開(kāi)發(fā)一款成功產(chǎn)品的前提,但每一項(xiàng)也都可以形成一個(gè)學(xué)科,是一個(gè)獨(dú)立的崗位,隨著敏捷開(kāi)發(fā)的流行,以及來(lái)到了體驗(yàn)為王的時(shí)代,現(xiàn)代軟件開(kāi)發(fā)更多的是注重效率和敏捷,而不是循規(guī)蹈矩的遵循這些開(kāi)發(fā)流程,比如軟件開(kāi)發(fā)的崗位不再僅僅是個(gè)技術(shù)崗位,它需要去參與前期的設(shè)計(jì)和評(píng)審、可以在視覺(jué)和交互方面提出自己的見(jiàn)解,在開(kāi)發(fā)的過(guò)程中需要自測(cè)程序盡快解決現(xiàn)存問(wèn)題,運(yùn)營(yíng)和維護(hù)的過(guò)程中也需要軟件的幫助。可見(jiàn)現(xiàn)代軟件開(kāi)發(fā)對(duì)開(kāi)發(fā)者的綜合素質(zhì)(這并不是facebook所講的全棧工程師)越來(lái)越高,自稱為碼農(nóng)或者程序猿顯然是不合理的,因?yàn)檫@個(gè)過(guò)程是腦力勞動(dòng)和體力腦動(dòng)并存,稱呼自己為工程師顯得更為合理。

策劃:需求收集(通過(guò)用戶調(diào)研、灰度發(fā)布、大數(shù)據(jù)分析、競(jìng)品分析、領(lǐng)導(dǎo)拍腦袋等方式獲取需求)、需求整理(將需求歸類、劃分優(yōu)先級(jí)等)、將需求轉(zhuǎn)換成解決方案(輸出設(shè)計(jì)文檔);

交互:從心理學(xué)(利用人性的弱點(diǎn))、人性化(心智)、個(gè)性化的角度將解決方案轉(zhuǎn)換成可交互的功能和界面(需要輸出交互文檔),比如加載等待、消息提示、頁(yè)面布局、頁(yè)面內(nèi)和頁(yè)面間的交互邏輯、頁(yè)面切換動(dòng)畫等等,這個(gè)過(guò)程中一般會(huì)使用Axure或者PowerPoint來(lái)制作交互文檔;

視覺(jué):根據(jù)交互圖,使用PhotoShop來(lái)做視覺(jué)效果,在Android上的圖片格式大多是png和jpg,對(duì)于需要屏幕適配,程序又適合做屏幕適配的地方可以使用九圖,格式為*.9.png。

軟件:根據(jù)視覺(jué)和交互效果將需求轉(zhuǎn)化為具體的實(shí)現(xiàn),在實(shí)現(xiàn)的過(guò)程中可能會(huì)因?yàn)樾枨蟆⒔换セ蛘咭曈X(jué)的變動(dòng)導(dǎo)致軟件實(shí)現(xiàn)的變動(dòng),因?yàn)椴邉潯⒔换ァ⒁曈X(jué)這每一個(gè)環(huán)節(jié)都可能會(huì)有信息失真的現(xiàn)象,或者是由于市場(chǎng)環(huán)境的變化、獲取信息不夠準(zhǔn)確、領(lǐng)導(dǎo)拍腦袋等等情況導(dǎo)致軟件始終處于被動(dòng)狀態(tài),所以現(xiàn)在會(huì)提倡敏捷開(kāi)發(fā)、結(jié)對(duì)編程、程序設(shè)計(jì)、同行評(píng)審、單元測(cè)試來(lái)提高程序的靈活性和穩(wěn)定性;

測(cè)試:軟件達(dá)到可交互的標(biāo)準(zhǔn)后,需要將可交互的程序提供測(cè)試,其中灰度發(fā)布(用戶測(cè)試)、自測(cè)(開(kāi)發(fā)自測(cè))、SQA(品質(zhì)保證)都算是測(cè)試;

維護(hù)和運(yùn)營(yíng):通過(guò)測(cè)試程序達(dá)到穩(wěn)定標(biāo)準(zhǔn)后,軟件就可以上線了,軟件上線后,需要去維護(hù),用戶反饋的問(wèn)題要及時(shí)解決、用戶有疑問(wèn)要及時(shí)解答;根據(jù)后臺(tái)統(tǒng)計(jì)信息、抓住可運(yùn)營(yíng)的節(jié)日、民族文化需要做運(yùn)營(yíng)來(lái)提高用戶使用產(chǎn)品的粘度,讓更多的用戶知道、使用產(chǎn)品都是運(yùn)營(yíng)應(yīng)該做的。

注:

可以查看這個(gè)答案了解一個(gè)APP從創(chuàng)意到上線的具體流程,開(kāi)發(fā)一個(gè)APP有多難?

可以查看筆戈科技的這篇文章了解一個(gè)手機(jī)(平板或其它電子產(chǎn)品也差不多)的誕生需要哪些環(huán)節(jié),一個(gè)手機(jī)的誕生過(guò)程

提問(wèn)的智慧

大多數(shù)工作都是以結(jié)果為導(dǎo)向的,特別是軟件開(kāi)發(fā)這個(gè)職業(yè),績(jī)效考核、KPI這些都是在考核你工作的成果,所以工作更多地是需要你解決問(wèn)題的能力,至于學(xué)習(xí)這個(gè)事情,還是在工作之外的時(shí)間去做吧。對(duì)于提高解決問(wèn)題能力我有兩個(gè)建議:

學(xué)會(huì)學(xué)習(xí)和思考:學(xué)習(xí)的過(guò)程中要廣度和深度并存,Android應(yīng)用開(kāi)發(fā)本身對(duì)技術(shù)功底的要求不高(因?yàn)楹芏嗟讓拥臇|西都被google、框架、開(kāi)源代碼給封裝起來(lái)了,多數(shù)時(shí)候你只需要看ReadMe或者API知道怎么用就可以了),更多地是在你遇到問(wèn)題的時(shí)候知道這個(gè)問(wèn)題能夠通過(guò)什么方法和方式來(lái)解決。書要看,但多逛逛論壇、QQ群、Github、StackOverflow、CSDN博客專欄對(duì)自己都是有益的。

學(xué)會(huì)提問(wèn):你身邊有很多資源,比如同事、StackOverflow、QQ技術(shù)交流群、搜索引擎,當(dāng)你遇到問(wèn)題的時(shí)候完全可以利用身邊的資源來(lái)解決遇到的問(wèn)題,如果一個(gè)問(wèn)題在一個(gè)小時(shí)之內(nèi)自己都不能夠解決它,我就會(huì)通過(guò)搜索引擎、Github、QQ技術(shù)交流群、同事、StackOverflow(以上排序是按優(yōu)先級(jí)排列的)來(lái)解決它。如果你需要好的答案你就需要有好的提問(wèn),特別是在QQ群或者論壇,在提問(wèn)的過(guò)程中需要體現(xiàn)出你的思考,能夠通過(guò)搜索引擎解決的問(wèn)題堅(jiān)決不問(wèn)他人,這是對(duì)別人的尊重,在這里推薦幾個(gè)鏈接,認(rèn)真看會(huì)對(duì)你有莫大的幫助:

如何用好 Google 等搜索引擎?

程序員應(yīng)該如何提問(wèn)?

提問(wèn)的智慧

Smart Questions

解決bug的方法

為了寫這一項(xiàng)我專門在知乎上提過(guò)一個(gè)問(wèn)題:

你有哪些解決bug的技巧?

在知道如何快速解決bug之前,你需要知道什么是bug。沒(méi)有完成策劃、交互、視覺(jué)要求的功能,這不叫bug,這叫功能缺陷;一個(gè)功能完成后不能正常使用也不叫bug,因?yàn)樗具€沒(méi)達(dá)到可測(cè)試的標(biāo)準(zhǔn)。我認(rèn)為當(dāng)你的程序達(dá)到可測(cè)試標(biāo)準(zhǔn)之后發(fā)現(xiàn)的問(wèn)題才叫bug。綜合我自己解決bug的經(jīng)驗(yàn)和知乎上的回答,總結(jié)常見(jiàn)的解決bug的方法有(你想要高效解決bug的前提是你能夠快速定位到缺陷所在的位置,所以以下方法多數(shù)講的是如何快速定位問(wèn)題,至于真正解決bug,需要你自己修改程序才行):

斷點(diǎn)調(diào)試:

以Eclipse為例:

1、打斷點(diǎn):

(1)打斷點(diǎn):

 

所有Android開(kāi)發(fā)人員都要知道這些

(2)清除斷點(diǎn):

 

2、啟動(dòng)調(diào)試模式的兩種方式:

(1)通過(guò)debug as啟動(dòng)調(diào)試程序:右鍵工程名--]Debug AS --]Android Application --]模擬器或者真機(jī)會(huì)彈出......watching for the debugger......的提示框,不要點(diǎn)擊等待其自動(dòng)消失 --] 此時(shí)已經(jīng)進(jìn)入調(diào)試模式,操作程序到達(dá)打斷點(diǎn)的地方。

(2)在程序運(yùn)行過(guò)程中,在DDMS視圖下選中要調(diào)試的程序,啟動(dòng)調(diào)試模式:

 

3、調(diào)試:請(qǐng)自行嘗試F5、F6、F7、F8這幾個(gè)調(diào)試的快捷鍵;

4、watch成員變量:在調(diào)試的過(guò)程中,比如在執(zhí)行for、while、do while循環(huán)、遞歸、系統(tǒng)回調(diào)等程序時(shí)可以通過(guò)watch來(lái)觀察成員變量或者方法返回值的變化情況,watch的方法:

 

所有Android開(kāi)發(fā)人員都要知道這些

注:更多關(guān)于在Eclipse IDE中調(diào)試Android程序的知識(shí)請(qǐng)參見(jiàn):Android eclipse中程序調(diào)試

打印:

打印調(diào)試的方法對(duì)于循環(huán)、異步加載、遞歸、JNI等代碼段非常有用,特別是在循環(huán)中,在循環(huán)次數(shù)非常大時(shí),通過(guò)打斷點(diǎn)調(diào)試顯然是一件費(fèi)力的事情,這時(shí)候打印就顯得更“智能”了,我通常會(huì)通過(guò)下面封裝的打印調(diào)試類來(lái)輸出打印信息,這個(gè)類可以打印print、log、行號(hào)、文件名、StrictMode等信息,當(dāng)不需要打印信息時(shí),只需要將DEBUG_MODE改為false就可以了:

 

  1. import android.content.Context; 
  2. import android.os.StrictMode; 
  3. import android.util.Log; 
  4. import android.widget.Toast; 
  5. /** 
  6. * 調(diào)試打印類 
  7. * 
  8. * */ 
  9. public class DebugUtils{ 
  10. private DebugUtils( ){ 
  11. public static void println( String printInfo ){ 
  12. if( Debug.DEBUG_MODE && null != printInfo ){ 
  13. System.out.println( printInfo ); 
  14. public static void print( String printInfo ){ 
  15. if( Debug.DEBUG_MODE && null != printInfo ){ 
  16. System.out.print( printInfo ); 
  17. public static void printLogI( String logInfo ){ 
  18. printLogI( TAG, logInfo ); 
  19. public static void printLogI( String tag, String logInfo ){ 
  20. if( Debug.DEBUG_MODE && null != tag && null != logInfo ){ 
  21. Log.i( tag, logInfo ); 
  22. public static void printLogE( String logInfo ){ 
  23. printLogE( TAG, logInfo ); 
  24. public static void printLogE( String tag, String logInfo ){ 
  25. if( Debug.DEBUG_MODE && null != tag && null != logInfo ){ 
  26. Log.e( tag, logInfo ); 
  27. public static void printLogW( String logInfo ){ 
  28. printLogW( TAG, logInfo ); 
  29. public static void printLogW( String tag, String logInfo ){ 
  30. if( Debug.DEBUG_MODE && null != tag && null != logInfo ){ 
  31. Log.w( tag, logInfo ); 
  32. public static void printLogD( String logInfo ){ 
  33. printLogD( TAG, logInfo ); 
  34. public static void printLogD( String tag, String logInfo ){ 
  35. if( Debug.DEBUG_MODE && null != tag && null != logInfo ){ 
  36. Log.d( tag, logInfo ); 
  37. public static void printLogV( String logInfo ){ 
  38. printLogV( TAG, logInfo ); 
  39. public static void printLogV( String tag, String logInfo ){ 
  40. if( Debug.DEBUG_MODE && null != tag || null != logInfo ){ 
  41. Log.v( tag, logInfo ); 
  42. public static void printLogWtf( String logInfo ){ 
  43. printLogWtf( TAG, logInfo ); 
  44. public static void printLogWtf( String tag, String logInfo ){ 
  45. if( Debug.DEBUG_MODE && null != tag && null != logInfo ){ 
  46. Log.wtf( tag, logInfo ); 
  47. public static void showToast( Context context, String toastInfo ){ 
  48. ifnull != context && null != toastInfo ){ 
  49. Toast.makeText( context, toastInfo, Toast.LENGTH_LONG ).show( ); 
  50. public static void showToast( Context context, String toastInfo, int timeLen ){ 
  51. ifnull != context && null != toastInfo && ( timeLen ] 0 ) ){ 
  52. Toast.makeText( context, toastInfo, timeLen ).show( ); 
  53. public static void printBaseInfo( ){ 
  54. if( Debug.DEBUG_MODE ){ 
  55. StringBuffer strBuffer = new StringBuffer( ); 
  56. StackTraceElement[ ] stackTrace = new Throwable( ).getStackTrace( ); 
  57. strBuffer.append( "; class:" ).append( stackTrace[ 1 ].getClassName( ) ) 
  58. .append( "; method:" ).append( stackTrace[ 1 ].getMethodName( ) ) 
  59. .append( "; number:" ).append( stackTrace[ 1 ].getLineNumber( ) ) 
  60. .append( "; fileName:" ).append( stackTrace[ 1 ].getFileName( ) ); 
  61. println( strBuffer.toString( ) ); 
  62. public static void printFileNameAndLinerNumber( ){ 
  63. if( Debug.DEBUG_MODE ){ 
  64. StringBuffer strBuffer = new StringBuffer( ); 
  65. StackTraceElement[ ] stackTrace = new Throwable( ).getStackTrace( ); 
  66. strBuffer.append( "; fileName:" ).append( stackTrace[ 1 ].getFileName( ) ) 
  67. .append( "; number:" ).append( stackTrace[ 1 ].getLineNumber( ) ); 
  68. println( strBuffer.toString( ) ); 
  69. public static int printLineNumber( ){ 
  70. if( Debug.DEBUG_MODE ){ 
  71. StringBuffer strBuffer = new StringBuffer( ); 
  72. StackTraceElement[ ] stackTrace = new Throwable( ).getStackTrace( ); 
  73. strBuffer.append( "; number:" ).append( stackTrace[ 1 ].getLineNumber( ) ); 
  74. println( strBuffer.toString( ) ); 
  75. return stackTrace[ 1 ].getLineNumber( ); 
  76. }else
  77. return 0
  78. public static void printMethod( ){ 
  79. if( Debug.DEBUG_MODE ){ 
  80. StringBuffer strBuffer = new StringBuffer( ); 
  81. StackTraceElement[ ] stackTrace = new Throwable( ).getStackTrace( ); 
  82. strBuffer.append( "; number:" ).append( stackTrace[ 1 ].getMethodName( ) ); 
  83. println( strBuffer.toString( ) ); 
  84. public static void printFileNameAndLinerNumber( String printInfo ){ 
  85. ifnull == printInfo || !Debug.DEBUG_MODE ){ 
  86. return
  87. StringBuffer strBuffer = new StringBuffer( ); 
  88. StackTraceElement[ ] stackTrace = new Throwable( ).getStackTrace( ); 
  89. strBuffer.append( "; fileName:" ).append( stackTrace[ 1 ].getFileName( ) ) 
  90. .append( "; number:" ).append( stackTrace[ 1 ].getLineNumber( ) ).append( "\n" ) 
  91. .append( ( null != printInfo ) ? printInfo : "" ); 
  92. println( strBuffer.toString( ) ); 
  93. public static void showStrictMode( ) { 
  94. if (DebugUtils.Debug.DEBUG_MODE) { 
  95. StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 
  96. .detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build()); 
  97. StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 
  98. .detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build()); 
  99. public static void d(String tag, String msg){ 
  100. if(DebugUtils.Debug.DEBUG_MODE){ 
  101. Log.d(tag, msg); 
  102. public class Debug{ 
  103. public static final boolean DEBUG_MODE = true
  104. public static final String TAG = "Debug"
  105. }  

目視法:

這適合于code review,但是不太靠譜,因?yàn)槿说木Ξ吘褂邢蓿袝r(shí)候你多敲一個(gè)分號(hào),縮進(jìn)不對(duì)都有可能導(dǎo)致程序出現(xiàn)問(wèn)題,但在代碼量較少時(shí)是一個(gè)高效率的方法。

自動(dòng)化測(cè)試:

Android的自動(dòng)化測(cè)試(分白盒測(cè)試和黑盒測(cè)試)工具有:monkey、Robotium、Appium、云端測(cè)試(比如testin),具體用法可參見(jiàn):

android實(shí)用測(cè)試方法之Monkey與MonkeyRunner

Robotium

Testin

Appium中文教程

排除法:

調(diào)試、打印、目視這三種方法適合于可以復(fù)現(xiàn)的問(wèn)題,對(duì)于隨機(jī)問(wèn)題(實(shí)際上不存在隨機(jī)問(wèn)題,只是問(wèn)題不那么容易復(fù)現(xiàn)而已),比如在線程、音頻播放、AnsynTask、Timer切換或者結(jié)束時(shí)剛好做了相應(yīng)地人為操作導(dǎo)致出現(xiàn)靈異現(xiàn)象。這時(shí)候可以通過(guò)排除法來(lái)排查問(wèn)題,具體的方法是首先大概定位到出現(xiàn)問(wèn)題的位置,然后將代碼一段一段地注釋,觀察程序現(xiàn)象,逐步縮小出現(xiàn)問(wèn)題的范圍。

版本管理介紹

在較大的軟件開(kāi)發(fā)過(guò)程中,可能有多個(gè)軟件工程師同時(shí)開(kāi)發(fā)一個(gè)項(xiàng)目的情況,比如有負(fù)責(zé)讀取數(shù)據(jù)、獲取網(wǎng)絡(luò)數(shù)據(jù)等API封裝的,有負(fù)責(zé)程序架構(gòu)的,有負(fù)責(zé)上層界面實(shí)現(xiàn)的,為了能夠最終編譯一個(gè)完成的程序出來(lái),需要將代碼整合,這個(gè)時(shí)候最方便的方法就是使用版本管理工具,固定時(shí)間上傳(比如每天、沒(méi)改動(dòng)一個(gè)功能等等),這樣能夠?qū)崟r(shí)保證服務(wù)器上的代碼是最完整、最新的,也可以避免由于自然災(zāi)害、電腦異常導(dǎo)致本地電腦掛掉損失掉代碼的問(wèn)題。

常見(jiàn)的版本管理工具有SVN和Git,我也使用過(guò)CVS,關(guān)于版本管理工具的介紹參見(jiàn):

版本控制

版本控制系統(tǒng)的選擇之路

git教程

git簡(jiǎn)易指南

注:對(duì)于windows用戶來(lái)說(shuō),建議使用烏龜殼系列的版本控制客戶端,使用github的朋友可以使用github for windows客戶端:

 

    tortoisegit 
     
    tortoisecvs 
     
    tortoisesvn 
     
    github for windows 

 

編譯

通常我們用Eclipse或者Android Studio開(kāi)發(fā)android程序時(shí),只需要運(yùn)行程序就可以在模擬器或者機(jī)器上運(yùn)行程序了,但為了保證代碼的完整性、能夠在服務(wù)器上編譯,需要通過(guò)編譯工具將代碼編譯成apk,常見(jiàn)的編譯工具有:ant、gradle,但這兩種編譯工具都是需要通過(guò)手動(dòng)敲命令來(lái)完成編譯功能(當(dāng)然你也可以自己寫腳本來(lái)實(shí)現(xiàn)編譯自動(dòng)化),jenkins是一個(gè)持續(xù)集成的工具,通過(guò)它可以代碼克隆、編譯以及程序加密自動(dòng)化,其實(shí)它也是通過(guò)批處理來(lái)實(shí)現(xiàn)的,ant、gradle和jenkins的具體用法自行谷歌,使用起來(lái)很簡(jiǎn)單,目前android studio和github上很多功能都是通過(guò)gradle來(lái)編譯的。

專業(yè)術(shù)語(yǔ)介紹

以下解釋完全是本人的理解,詳細(xì)解釋可自行谷歌。

版本迭代:按照需求優(yōu)先級(jí),在保證基本功能OK后持續(xù)開(kāi)發(fā)和升級(jí),這樣能夠降低軟件開(kāi)發(fā)的風(fēng)險(xiǎn),并且能夠及時(shí)解決用戶反饋的問(wèn)題,船小好掉頭嘛;

敏捷開(kāi)發(fā):小步快跑,大概意思就是不要過(guò)于注重文檔,要注重當(dāng)面交流,能夠在實(shí)現(xiàn)時(shí)高保真的還原用戶的需求場(chǎng)景,并且能夠快速地解決用戶的需求。

單元測(cè)試:白盒測(cè)試的一種,對(duì)核心方法通過(guò)寫程序來(lái)測(cè)試自己的程序,單元測(cè)試的目的是讓你有意識(shí)地降低程序間的耦合,保證每一個(gè)方法都是最小單元,但這對(duì)于測(cè)試程序邏輯是沒(méi)有幫助,這是我自己的理解。。。

灰度發(fā)布:先找一部分用戶來(lái)使用即將發(fā)布的程序(這部分用戶可以是隨機(jī)抽取、制定年齡段、指定地區(qū)或者通過(guò)某種方式知道他是活躍用戶),在測(cè)試的過(guò)程中給與用戶一點(diǎn)好處讓用戶寫用戶體驗(yàn)報(bào)告、反饋問(wèn)題等方式來(lái)發(fā)現(xiàn)程序存在的問(wèn)題和缺陷;

DA統(tǒng)計(jì):也叫后臺(tái)統(tǒng)計(jì),通過(guò)在程序中埋點(diǎn)的方式,在有網(wǎng)絡(luò)的情況下將用戶的操作行為和數(shù)據(jù)上傳到后臺(tái),將每個(gè)用戶的信息都上傳回來(lái)就叫大數(shù)據(jù),通過(guò)建模對(duì)這些數(shù)據(jù)分析就叫大數(shù)據(jù)分析。

開(kāi)放平臺(tái):比如分享到QQ空間、分享到微信、訊飛語(yǔ)音、友盟的后臺(tái)統(tǒng)計(jì)、天氣、地圖等等都叫做開(kāi)放平臺(tái),它提供了一些開(kāi)放的接口給開(kāi)發(fā)者,方便開(kāi)發(fā)者使用它的服務(wù),開(kāi)放平臺(tái)多數(shù)服務(wù)都是免費(fèi)的,但有時(shí)候也可能不穩(wěn)定,比如用的人少它自然就活不下去了,然后就沒(méi)有然后了。

同行評(píng)審:你的同行和你一起看看你的代碼,發(fā)現(xiàn)是否有問(wèn)題;

結(jié)對(duì)編程:在寫代碼的過(guò)程中,有個(gè)人坐在你旁邊或者你坐在別人旁邊,編寫邊討論,降低程序出現(xiàn)邏輯和低級(jí)錯(cuò)誤的概率。

Android開(kāi)發(fā)資源

參見(jiàn)我的另一篇文章:Android開(kāi)發(fā)者網(wǎng)址導(dǎo)航

建議

盡量閱讀官方文檔,這才是原汁原味、不失真的開(kāi)發(fā)指導(dǎo);

即使你認(rèn)為設(shè)計(jì)程序是浪費(fèi)時(shí)間,你只是喜歡寫程序,至少你也得用思維導(dǎo)圖理清思路,思維導(dǎo)圖對(duì)于幫助你理解設(shè)計(jì)文檔、理清思路有很大的幫助;

不要用Intent傳遞大量的數(shù)據(jù),這有可能導(dǎo)致ANR或者報(bào)異常;

在退出頁(yè)面后,系統(tǒng)不一定會(huì)及時(shí)執(zhí)行onDestory方法,如果你在onDestory方法里做關(guān)閉文件、釋放內(nèi)存的操作可能出現(xiàn)退出程序又立即進(jìn)入時(shí),由于需要重新初始化這些信息導(dǎo)致代碼重入的異常;

在改動(dòng)JNI后,運(yùn)行程序之前記得卸載掉已經(jīng)安裝在模擬器或者真機(jī)上的該程序,如果直接運(yùn)行,android不會(huì)load最新編譯的so,也就不能立即看到修改后的效果;

代碼至少每天備份一次,或者是完善一個(gè)功能就備份一次,不要堆積之后一次性備份,因?yàn)樵谀愕拇a出問(wèn)題需要回溯代碼時(shí)你需要從服務(wù)器上重新取代碼,同時(shí)也可以避免代碼不是最新導(dǎo)致最后和其他人合并時(shí)不知道改了哪些地方;

將打印信息封裝成一個(gè)方法,用一個(gè)標(biāo)志位控制這個(gè)這個(gè)方法的方法體是否需要執(zhí)行,這樣在由debug版釋放到release版本時(shí),不需要傻傻地一行一行地去掉代碼,你只需要改變標(biāo)志位的值就可以了;

對(duì)于有返回值的JNI函數(shù),即使你不返回任何值,用NDK編譯JNI的時(shí)候也不會(huì)報(bào)錯(cuò),所以在寫JNI代碼的時(shí)候,一定要仔細(xì)檢查代碼;

JNI頻繁讀寫文件操作會(huì)影響程序的運(yùn)行性能,可以考慮一次性在內(nèi)存中申請(qǐng)一塊大內(nèi)存作為緩存空間,用這種空間換時(shí)間的方式可以大大提高程序的運(yùn)行效率;

不要指望類的finalize方法去處理需要回收和銷毀的工作,因?yàn)閒inalize是系統(tǒng)回調(diào)的方法,調(diào)用時(shí)機(jī)不可預(yù)見(jiàn),切記;

使用文件流、Cursor時(shí),使用結(jié)束后記得一定要關(guān)閉,否則可能導(dǎo)致內(nèi)存泄漏,嚴(yán)重的情況可能引發(fā)程序崩潰;

優(yōu)先使用Google搜索引擎(少用百度),如果不能正常使用Google搜索引擎建議通過(guò)代理、VPN、修改hosts文件等方式搭建梯子。這里提供一個(gè)免費(fèi)的谷歌搜索引擎

對(duì)于不需要使用硬件加速的activity(沒(méi)有動(dòng)畫效果、視頻播放以及各種多媒體文件的操作都可以關(guān)掉硬件加速),在AndroidManifest.xml文件中通過(guò)“android:hardwareAccelerated="false"”關(guān)掉硬件加速可節(jié)省應(yīng)用內(nèi)存;

對(duì)于需要橫豎屏轉(zhuǎn)換的應(yīng)用,又不想在橫豎屏切換的時(shí)候重新跑onCreate方法,可以在AndroidManifest.xml文件中對(duì)應(yīng)的Activity標(biāo)簽下調(diào)用“android:configChanges="screenSize|orientation"”;

為了減輕應(yīng)用程序主進(jìn)程的內(nèi)存壓力,對(duì)于耗內(nèi)存比較多的界面(比如視頻播放界面、flash播放界面等),可以在AndroidManifest.xml文件中對(duì)應(yīng)的Activity標(biāo)簽下調(diào)用“android:process=".processname"”單開(kāi)一個(gè)進(jìn)程,但在退出這個(gè)界面的時(shí)候一定要在該界面的onDestory方法中調(diào)用System的kill方法來(lái)殺掉該進(jìn)程;

在res/values/arrays.xml文件中定義的單個(gè)數(shù)組的元素個(gè)數(shù)不宜過(guò)大,過(guò)大會(huì)導(dǎo)致加載數(shù)據(jù)時(shí)非常慢,有時(shí)候你需要使用數(shù)組資源時(shí)數(shù)據(jù)有可能還沒(méi)加載完成;

一個(gè)Activity中最耗費(fèi)內(nèi)存的是activity的背景(多數(shù)情況如此,特別是對(duì)于分辨率很大的機(jī)器,一個(gè)界面的背景算下來(lái)都需要好幾兆內(nèi)存),所以在程序界面較多時(shí),可以考慮將圖片轉(zhuǎn)換成靜態(tài)的drawable,然后多個(gè)activity共用這一張背景圖;

可以通過(guò)為application、activity自定義主題的方式來(lái)關(guān)掉多點(diǎn)觸摸功能,只需要在自定義的主題下添加這兩個(gè)標(biāo)簽:

 

  1. [item name="android:windowEnableSplitTouch"]false[/item] 
  2. [item name="android:splitMotionEvents"]false[/item] 

很多游戲進(jìn)入時(shí),播放的片頭動(dòng)畫多數(shù)是一個(gè)視頻文件;

Android單個(gè)dex文件的方法數(shù)不能超過(guò)65536個(gè),android使用多個(gè)dex能否避開(kāi)65536方法數(shù)限制?

使用模擬器genymotion代替android自帶模擬器(它需要虛擬機(jī)vituralbox的支持,不過(guò)官網(wǎng)已經(jīng)提供了一個(gè)集成虛擬機(jī)的安裝包了,直接下載下來(lái)安裝即可),可以大大提高使用模擬器的體驗(yàn)(流暢、快),它也可以以插件的形式集成在Eclipse中,這是視頻教程

給Application或者activity設(shè)置自定義主題時(shí),最好不要設(shè)置為全透明,否則在activity按Home鍵回退到桌面的時(shí)候效果很渣;

如果你需要取消toast顯示的功能,在一個(gè)類中你只需要實(shí)例化該類一次(也就是說(shuō)將Toast定義成一個(gè)全局的成員變量),這樣你就可以調(diào)用mToast.cancel()了,我把它寫成了一個(gè)靜態(tài)類:

 

  1. public class ToastUtils { 
  2. private ToastUtils( ){ 
  3. public static void showToast( Context context, String toast ){ 
  4. ifnull == mToast ){ 
  5. mToast = Toast.makeText( context, toast, Toast.LENGTH_LONG ); 
  6. }else
  7. mToast.setText( toast ); 
  8. mToast.show( ); 
  9. public static void cancel( ){ 
  10. ifnull != mToast ){ 
  11. mToast.cancel( ); 
  12. public static Toast mToast = null

你可以定義一個(gè)靜態(tài)類來(lái)實(shí)現(xiàn)防止按鈕被重復(fù)點(diǎn)擊導(dǎo)致重復(fù)執(zhí)行一段代碼的問(wèn)題:

 

  1. /** 
  2. * 按鈕重復(fù)點(diǎn)擊 
  3. * 
  4. * */ 
  5. public class BtnClickUtils { 
  6. private BtnClickUtils( ){ 
  7. public static boolean isFastDoubleClick() { 
  8. long time = System.currentTimeMillis(); 
  9. long timeD = time - mLastClickTime; 
  10. if ( 0 [ timeD && timeD [ 1000) { 
  11. return true
  12. mLastClickTime = time; 
  13. return false
  14. private static long mLastClickTime = 0

放在apk的assets或者raw目錄下的數(shù)據(jù)文件最好做加密處理,在需要使用的時(shí)候才解密,這樣可以避免在apk被他人破解時(shí)數(shù)據(jù)也被破解的問(wèn)題;

最好不要再activity的onCreate方法里面調(diào)用popupwindow的show方法,有可能由于activity沒(méi)有完全初始化導(dǎo)致程序異常(android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid),如果非要在一進(jìn)activity就顯示popupwindow,建議用handler.post、View.postDelay來(lái)處理;

對(duì)于自定義View,在構(gòu)造方法里面是獲取不到視圖的寬高的(此時(shí)獲取長(zhǎng)寬都為0),需要在onMeasure方法中或者跑了onMeasure方法后才能夠獲取到視圖的寬高,不過(guò)你可以通過(guò)在構(gòu)造方法里面強(qiáng)制測(cè)量視圖的寬高來(lái)實(shí)現(xiàn)在構(gòu)造方法里獲取視圖的寬高信息,具體見(jiàn)MeasureSpec介紹及使用詳解

如果你覺(jué)得在安裝Eclipse后還需要配置android開(kāi)發(fā)環(huán)境很麻煩,你可以直接使用ADT Bundle,它是一個(gè)懶人套餐,下載下來(lái)就可以用了,可以在這里下載。

有時(shí)間看看阿里技術(shù)嘉年華、InfoQ演講與訪談、Google IO視頻,可以學(xué)習(xí)到一些解決問(wèn)題、做大項(xiàng)目的經(jīng)驗(yàn)。

當(dāng)應(yīng)用中動(dòng)畫比較多,并且動(dòng)畫都是通過(guò)圖片來(lái)切換的時(shí)候,可以考慮借用Cocos的精靈表單思想,這樣就可以避免圖片命名的煩惱。

工具推薦

代碼對(duì)比:Beyond compare

屏幕取色:ColorPix

梯子:紅杏

思維導(dǎo)圖: mindmanager

在線工具:在線工具

責(zé)任編輯:chenqingxiang 來(lái)源: 張明云 的簡(jiǎn)書
相關(guān)推薦

2012-07-31 09:52:54

HTML5

2013-06-28 14:19:20

2021-12-24 11:24:59

React HackReact JavaScript

2016-02-22 15:09:19

Android項(xiàng)目管理技巧

2010-07-30 16:27:06

Flex開(kāi)發(fā)

2011-05-26 11:13:36

Flex

2010-03-01 10:20:27

Flex

2014-07-17 09:31:50

iOS8SDK

2023-06-05 16:50:06

開(kāi)發(fā)TypeScriptJavaScript

2015-08-21 09:47:02

ios9sdk新特性

2017-06-09 13:33:57

2025-02-25 08:30:00

前端開(kāi)發(fā)VSCode

2018-09-29 15:27:05

BinderAPPAndroid

2024-04-26 13:36:01

2013-04-26 09:38:13

go

2015-09-18 08:41:12

androidM權(quán)限

2015-08-31 09:41:38

androidM權(quán)限

2015-08-11 08:41:58

游戲數(shù)據(jù)游戲開(kāi)發(fā)

2014-09-01 09:53:50

Android框架

2012-11-13 10:34:03

PythonWeb
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一级全黄视频 | 国产乱肥老妇国产一区二 | 久久久久久一区 | 毛片a区 | 1204国产成人精品视频 | 天天艹日日干 | 99久久久99久久国产片鸭王 | 天天拍天天操 | 黄色免费av | 综合精品 | 国产在线视频一区二区 | 四虎影院欧美 | 久久精品国产亚洲a | 国产一区二区影院 | 日韩中文一区二区三区 | 精品成人免费一区二区在线播放 | 亚洲国产成人av好男人在线观看 | 久久久久久九九九九九九 | 新超碰97 | 美日韩精品| 五月天激情电影 | 欧美精品综合在线 | 国产超碰人人爽人人做人人爱 | 欧美日韩亚洲国产综合 | 婷婷色国产偷v国产偷v小说 | 日韩视频一区二区 | 嫩草视频在线免费观看 | 亚洲日本中文 | 国产激情一区二区三区 | 欧美精产国品一二三区 | 久久久久国色av免费观看性色 | 中文字幕高清免费日韩视频在线 | 国产精品久久久久久久久久久久久 | 欧美www在线 | 日韩欧美精品 | 成人国产精品久久 | 天堂一区二区三区 | 国产一区二区三区久久久久久久久 | 欧美自拍第一页 | 日韩精品一区在线 | 亚洲欧洲日韩精品 中文字幕 |