1. 所有Activity可繼承自BaseActivity,便於統一風格與處理公共事件,構建對話框統一構建器的創建,萬一須要總體變更,一處修改處處有效。html
2. 若是數據沒有必要加載,數據請務必延遲初始化,謹記爲用戶節省內存,總不會有壞處。java
3. 作以前先考慮那些能夠公用,資源,layout,類,作一個結構、架構分析以加快開發,提高代碼可複用度。android
4. listview在數據未滿一屏時,setSelection函數不起做用;ListView批量操做時各子項和視圖正確對應,可見即所選。c++
5. setSelection不起做用,嘗試smoothScrollToPosition。ListView的LastVisiblePosition(最後一個可見子項)會隨着getView方法執行位置不一樣變更而變。git
6. 控制Activity的代碼量,保持主要邏輯清晰。其餘類遵照SRP(單一職能),ISP(接口隔離)原則。github
7. 與Activity通信使用Handler更方便; 若是你的框架回調鏈變長,考慮監聽者模式簡化回調。sql
8. Handler在子線程線程使用Looper.prepare,或者new的時候給構造函數傳入MainLooper來確保在主線程run。數據庫
9. timepicker 點擊肯定後須要clearFocus才能獲取手動輸入的時間。api
10.ExpandableListView的子列表不能點擊(禁用)要把Adapter的isChildSelectable方法返回true。數組
11.UI顯示注意內容過長的情形要提早使用ScrollView不然在小手機上尷尬。
12.注意按鈕的感應範圍不小於9mm不然不易點擊;輸入框注意光標的位置更易用戶輸入。
13.常常須要用ListView或者其它顯示大量Items的控件實時跟蹤或者查看信息,而且但願最新的條目能夠自動滾動到可視範圍內。經過設置的控件transcriptMode屬性能夠將Android平臺的控件(支持ScrollBar)自動滑動到最底部。
14. EditText在setText時不要忘記是否須要setSelection。在大多數狀況下是須要設置的。
15. 輸入控件注意對空格、換行等符號的控制;輸入框裏內容注意和左右控件的空間,防止誤點擊。
16.XML兩種狀況要注意:1 屬性名字時候有重複;2 注意文本是否包含非法字符,注意使用CDATA包裹。
17.當咱們的頁面變得複雜,XML文件內容過多時,<include />標籤能夠有效地幫助咱們整理文件內容,同時提升了XML文件的可讀性。同時,它的用法也與Fragment相似。
18.ViewStub是一個極佳的延遲加載視圖資源的方式。只要你設計的視圖是依賴於上下文來改變其可見性的,就利用ViewStub類吧。也許當你只將其應用在一個簡單的頁面當中時,並不會感受到在性能上有任何提高,可是在複雜頁面中,它的效果是極佳的。
ViewStub是一個不可見、不佔空間(zero-sized)的控件,它能夠用來在運行時延遲加載視圖資源。只有當咱們將ViewStub的可見性設爲true,或者調用inflate()方法,它的視圖資源纔會被加載。
main.xml <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "fill_parent" > <Button android:layout_width ="fill_parent" android:layout_height ="wrap_content" android:layout_gravity ="center_vertical" android:onClick ="onShowMap" android:text ="@string/show_map" /> <ViewStub android:id ="@+id/map_stub" android:layout_width ="fill_parent" android:layout_height ="fill_parent" android:inflatedId ="@+id/map_view" android:layout ="@layout/map" /> </RelativeLayout> map.xml <com.google.android.maps.MapView xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:apiKey= "my_api_key" android:clickable= "true" />
//MainActivity public class MainActivity extends MapActivity { private View mViewStub; @Override public void onCreate (Bundle savedInstanceState ) { super. onCreate( savedInstanceState ); setContentView( R. layout. main); mViewStub = findViewById( R. id. map_stub); } public void onShowMap (View v) { mViewStub. setVisibility (View .VISIBLE ); } }
19.如何將一個Button放置在佈局中間並將其寬度設爲其parent的50%?
在此咱們將weightSum屬性與layout_weight屬性一塊兒利用。
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:background= "#ffffff" android:gravity= "center" android:orientation= "horizontal" android:weightSum= "1" ><!--1.添加android:weightSum屬性--> <Button android:layout_width ="0dp"<!--2.將Button的layout_width設爲0dp--> android:layout_height ="wrap_content" android:layout_weight ="0.5"<!--3.確保其佔用了50%的可用空間--> android:text ="@string/activity_main_click_me" /> </LinearLayout>
能夠注意到,在第2步將Button的layout_width設爲了0dp,會不會與layout_weight有衝突?答案是不會:
一個控件的寬度是這樣計算出來的:
Widget's width + Widget's weight*Parent's width/Parent's weightSum
20.如何處理須要填充的數據爲空的狀況?
ListView及其餘繼承自AdapterView的類都有一個簡便的處理這種狀況的方法:setEmptyView(View)。
當ListView的Adapter爲空或者Adapter的isEmpty()方法返回true的時候,它將會把設置的emptyview繪製出來。
<FrameLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:orientation= "vertical" > <ListView android:id ="@+id/my_list_view" android:layout_width ="fill_parent" android:layout_height ="fill_parent" /> <ImageView android:id ="@+id/empty_view" android:layout_width ="fill_parent" android:layout_height ="fill_parent" android:src ="@drawable/empty_view" /> </FrameLayout>
再來看自定義的drawable/empty_view文件:
<shape xmlns:android = "http://schemas.android.com/apk/res/android" android:shape= "rectangle" > <solid android:color= "#AA00FF00" /> </shape>
是一個自定義的shape,當ListView沒數據的時候才展示出來.
public class MainActivity extends Activity { private ListView mListView; @Override public void onCreate (Bundle savedInstanceState ) { super. onCreate( savedInstanceState ); setContentView (R .layout .main ); mListView = (ListView ) findViewById (R .id .my_list_view ); mListView. setEmptyView (findViewById (R .id .empty_view )); /*String[] strs=new String[]{"1","2"}; ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,strs); mListView.setAdapter(adapter);*/ } }
21.咱們能夠利用兩個TextView來顯示,第一個TextView顯示LED屏上默認不發光的88:88:88,另外一個顯示實時的時間並添加發光及陰影效果。可是咱們還須要解決顯示的字體問題,讓它看起來更像是一個真實的LED數字時鐘。
解決步驟:
(1)自定義一個LedTextView類,繼承自TextView,這個類主要用來設置和顯示字體;
(2)在MainActivity中新開啓一個線程用來更新LedTextView顯示的時間;
(3)爲LedTextView添加陰影效果,看起來更真實。
在assets文件夾下放入一個咱們須要用到的字體文件:digital-7.ttf
public class LedTextView extends TextView { private static final String FONTS_FOLDER = "fonts"; private static final String FONT_DIGITAL_7 = FONTS_FOLDER + File.separator + "digital-7.ttf"; private void init(Context context) { AssetManager assets = context. getAssets(); final Typeface font = Typeface . createFromAsset( assets, FONT_DIGITAL_7); setTypeface (font );// 設置字體 } public LedTextView (Context context) { super(context ); init( context); } public LedTextView (Context context, AttributeSet attrs) { super(context , attrs ); init( context); } public LedTextView (Context context, AttributeSet attrs, int defStyle) { super(context , attrs , defStyle ); init( context); } }
<merge xmlns:android ="http://schemas.android.com/apk/res/android" > <com.vectoryi.hack011.view.LedTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/default_time" android:textColor="#3300ff00" android:textSize="80sp" /> <com.vectoryi.hack011.view.LedTextView android:id="@+id/main_clock_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="#00ff00" android:textSize="80sp" /> </merge>
22.判斷EditView值爲空
TextUtils.isEmpty(edit.getText()) //爲空的判斷
TextUtils.isEmpty(edit.getText().toString().trim()) //去掉空格
1. 全局變量放全局類中,模塊私有放本身的管理類中,讓常量清晰且集中。
2. 碼塊/常量/資源能夠集中公用的必定共用,即便共用邏輯稍複雜一點也會值得,修改起來很輕鬆,修改一種,處處有效。
3. 數據庫表段字段常量和SQL邏輯分離,更清晰。
4. 有序隊列操做add、delete操做時注意保持排序,不然你會比較難堪喔。
5. 數據庫刪除數據時,要注意級聯操做避免出現永遠刪不掉的髒數據喔。
6. 多線程操做數據庫時,db關閉了會報錯,也極可能出現互鎖的問題,推薦使用事務。
7. 完整型數據必定要用Sqlite的Transaction,大數據必定要用。粗略測試插入100個數據有20倍的提速,插入1000個數據就有100多倍的提速。
8. 存在多個不一樣的dbhelper實例狀況下,sqlitedatabase對象必然存在不一樣的實例,多線程同時寫入數據,輪流寫入數據時會不定時的報db is locked,引發崩潰,無論是操做同張表仍是異表。讀和寫能夠同時併發,輪流無規律的交替執行。同時寫入數據時解決方案是用併發的每一個線程都用事務,db則不會lock,按次總體寫入。
9.建議整個應用維護一個dbhelper實例,只要db沒有關閉,全局就只有一個db實例,多線程併發寫入db不會lock,嚴格交替進行寫入:123123123。。。(123表明不一樣線程,輪流插入一個記錄),讀和寫均不會鎖住db,讀寫交替並無規律,執行次數和程度看cpu分配給哪一個線程的時間片長。
10.一個任務使用事務嵌套N個事務,N個事務中有一個失敗,這個任務總體失敗,所有成功後,數據才寫入,具備安全性,總體性。而且事務寫入大批量數據的效率經實際測試成百上千倍的高於通常的單個寫入。數據庫大量數據、多線程操做建議使用LiteOrm數據庫框架,更穩定簡單。
11.推薦使用的數據庫框架:
LiteOrm庫:超級清晰且重心能夠放在業務上不用關心數據庫細節,自動化。使用方法:https://github.com/litesuits/android-lite-orm
ORMLite:鴻洋推薦,使用方法:http://blog.csdn.net/lmj623565791/article/details/39121377
12. 信息同步:無論是數據庫仍是網網絡操做,新插入的數據注意返回ID(若是沒有賦予惟一ID),不然至關於沒有同步。
13. arraylist執行remove時注意移除int和Integer的區別。
14.避免String=」null」的狀況出現String = null,=」」均可以。避免出現title=」無主題」這樣的數據提交到數據庫浪費空間。
15.編碼遇到讀寫、出入等邏輯要雙向考慮,文件導入導出,字符字節相互轉換都要兩邊轉碼。
16. 一個 int 值與一個 Integer 對象(能包含 int 值的最小對象)的大小比率約爲 1:4(32位和64位機器有不一樣)。額外的開銷源於 JVM 用於描述 Java 對象的元數據也就是 Integer,(Long、Double等也是)。
17. 對象由元數據和數據組成。元數據包括類(指向類的指針,描述了類的類型),標記(描述了對象狀態,如散列碼、形狀等),鎖(對象同步信息)。數組對象還包括大小的元數據。
18. 一個在 32 位 Java 運行時中使用 1GB Java 堆的 Java 應用程序在遷移到 64 位 Java 運行時以後,一般須要使用 1.7GB 的 Java 堆。
19. Hash 集合的訪問性能比任何 List 的性能都要高,但每條目的成本也要更高。因爲訪問性能方面的緣由,若是您正在建立大集合(例如,用於實現緩存),那麼最好使用基於 Hash 的集合,而沒必要考慮額外的開銷。
20. 延遲分配 Hashtable:若是 Hashtable 爲空是常常發生的廣泛現象,那麼僅在存在須要存儲的數據時分配 Hashtable 應該是一種合理的作法。將 Hashtable 分配爲準確的大小:雖然會有默認大小,但建議使用更爲準確的初始大小。、
21. 選擇正確的集合類型使你可以在集合性能與內存佔用之間達到合理的平衡。除此以外,你能夠經過正確調整集合大小來最大化填充率、最小化未獲得利用的空間,從而最大限度地減小內存佔用。
22. 對於並不那麼注重訪問性能的較小集合而言,List 則是合理的選擇。ArrayList 和 LinkedList 集合的性能大致相同,但其內存佔用徹底不一樣:ArrayList 的每條目大小要比 LinkedList 小得多,但它不是準確設置大小的。List 要使用的正確實現是 ArrayList 仍是 LinkedList 取決於 List 長度的可預測性。若是長度未知,那麼正確的選擇多是 LinkedList,由於集合包含的空白空間更少。若是大小已知或可預知或比較小,那麼 ArrayList 的內存開銷會更低一些。
23. 因爲String類的immutable性質,當String變量須要常常變換其值時,應該考慮使用StringBuilder提高性能,多線程使用StringBuffer操做string提升程序效率。
24. java 棧的優點是比堆速度快,可共享,主要存放臨時變量、參數等,堆的優點是可動態分配內存大小。
25. 只要是用new()來新建對象的,都會在堆中建立,並且其數據是單獨存值的,即便與棧中的數據(值)相同,也不會與棧中的數據共享。
26. 基本數據類型定義的變量稱自動變量,存的是‘字面值’,存在於棧中,可共享(存在即不新建)。
27.多個RandomAccessFile對象指向同一個文件,可以使用多個線程一塊兒寫入無需再本身加鎖,經試驗結論:三個線程分別寫入100萬次數據,使用鎖約12秒,不使用約8.5秒。100個線程分別寫入1萬次數據使用鎖耗時約4.2秒,不使用鎖耗時約3秒。
28.XmlPullParser解析慎用nextText()方法,xml比較複雜,含有空標籤、重複名字標籤時容易出現異常問題;TEXT中使用getText()方法代替START_TAG中使用nextText()方法;START_TAG,TEXT,END_TAG三個事件配合使用。注意每一個xml節點之間(無論是開始節點仍是結束節點)都會出現TEXT事件。
29. 注意函數參數裏的++或者–操做。是++c 仍是 c++,區別很大。
1. 不要相信龐大的管理類的東西會帶來什麼好處,多是一場災難,而要時刻注意單一職責原則,一個類專心作好一件事情更爲清晰。
2. 異常拋出,在合適的位置處理或者集中處理,不要搞的處處是catch,混亂且性能低,儘可能不要在循環體中捕獲異常,以提高性能。
3.地址引用鏈長時(3個以上指向)當心內存泄漏,和警戒堆棧地址指向,典型的易發事件是:數據更新了,ListView視圖卻沒有刷新,這時Adapter極可能指向並的並非你更新的數據容器地址(通常爲List)。
4. 關於形參實參:調用函數時參數爲基本類型傳的是值,即傳值;參數爲對象傳遞的是引用,即傳址。
5. Log請打上Tag,調試打印必定要作標記,能定位打印位置,不然尷尬是:不知道是哪裏在打印。
6. Long a; 判斷a有沒有賦值,if(a == 0)在a沒有賦值狀況下會報錯。應該if(a == null),Integer、Floag等也同樣,緣由你懂,只是提醒你要當心喔。
7. 構造函數裏面極度不推薦啓動異步線程,會埋下隱患。好比:異步線程調用了本例的示例,就會悲劇等着崩潰吧。
8. 千萬不要理所固然的覺得一個對象不會爲空,充分的作好容錯處理;另外注意null也能夠插入ArrayList等容器中。
9. 服務器和客戶端儘可能統一惟一標識(有多是ID),不然多少會有歧義和問題。
10. 註釋,儘可能去寫足夠的註釋,去描述一下思路,達到看了能夠明白某一塊代碼的效果。
11.監聽者模式不方便使用時,推薦EventBus框架庫,使用時間總線,沒接觸過的同窗能夠自行腦補一下哦。
12. 充分利用封裝(提供接口類來控制訪問數據)和委託(helper對象來實施任務)兩種理念。
13.當邏輯沒有明顯問題時考慮對象屬性、函數參數、網絡傳輸參數是否所有了解,是否設置正確。
14. 當出現編譯或者運行時錯誤,別人那沒問題時,考慮你的編譯環境和環境版本是否有問題。
15. 改變邏輯的時候考慮所有用到這項功能的地方,分散的地方多了,容易大意。
16. 當系統原生組件出現問題時,查看錯誤棧信息,本身寫一個該組件的子類,並在合適的地方將出錯方法複寫一下,加上try catch保證不崩潰掉。不要擾亂了該系統控件的正常邏輯。
17. 各類地方、永遠的不要小看null指針問題,甚至有些場合寧肯錯殺(try catch),不可放過。
18.MVC和MVP的區別
MVP將MVC中的Controller層進行了優化而生成了Presenter。Presenter單詞翻譯爲「提出者;任命者;主持人」,Presenter層和MVC的Controller同樣,負責核心邏輯,但不同的是Presenter經過接口協議進行數據傳遞,並阻斷了View和Model的直接聯繫,從而使View和Model更加專一於自身業務邏輯。
各個層之間經過接口協議進行溝通;
View和Model再也不進行直接交互;
1.android中獲取IP地址
public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { Log.e(LOG_TAG, ex.toString()); } return null; }
2.android獲取存儲卡路徑以及使用狀況
/** 獲取存儲卡路徑 */ File sdcardDir=Environment.getExternalStorageDirectory(); /** StatFs 看文件系統空間使用狀況 */ StatFs statFs=new StatFs(sdcardDir.getPath()); /** Block 的 size*/ Long blockSize=statFs.getBlockSize(); /** 總 Block 數量 */ Long totalBlocks=statFs.getBlockCount(); /** 已使用的 Block 數量 */ Long availableBlocks=statFs.getAvailableBlocks();
3.查看電池使用狀況:
Intent intentBatteryUsage = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY); startActivity(intentBatteryUsage);
4.刪除APK:
Uri uri =Uri.fromParts("package", strPackageName, null); Intent it = newIntent(Intent.ACTION_DELETE, uri); startActivity(it);
5.安裝APK
Uri installUri = Uri.fromParts("package","xxx", null); returnIt = newIntent(Intent.ACTION_PACKAGE_ADDED, installUri);
6.接收短信代碼
public class SMSReceiver extends BroadcastReceiver { /*當收到短信時,就會觸發此方法*/ public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Object messages[] = (Object[]) bundle.get( "pdus"); SmsMessage smsMessage[] = new SmsMessage[messages.length]; for (int n = 0; n < messages.length; n++) { smsMessage[n] = SmsMessage.createFromPdu(( byte[]) messages[n]); } //產生一個Toast Toast toast = Toast.makeText(context, "短信內容: " + smsMessage[0].getMessageBody(), Toast.LENGTH_LONG); //設置toast顯示的位置 //toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 200); //顯示該Toast toast.show(); } } XML中須要添加: [html] view plain copy print? <receiver android:name=".SMSReceiver" android:enabled="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>