對Android的惡意吐槽(勿看,有毒)
CSDN博客:http://blog.csdn.net/niu_gao
我覺得android系統中有一個特惡心人的大敗筆。就是這個大敗筆造成了android系統的卡卡卡不停。
這個大敗筆就是對activity的設計。
Android對activity的設計原則是:必須是執行時獨立的。
你不能直接創建activity並啟動它,必須由系統幫你這樣幹。你要啟動activity。必須用一個Intent請求系統幫忙。
所以你要在manifest文件裏聲明app中的每一個activity。假設你有多個activity聲明為可啟動的而且指定了intent-filter,那麽每一個activity都有可能成為你app的入口。
既然每一個activity都可能成為入口,那每一個activity必須是功能獨立。自我圓滿的。也就是說淡化了進程的概念,一個activity假設destroy了。即使它所在的app進程沒有退出且又啟動了新的activity。也應該視為這個activity的app退出了。
CSDN博客:http://blog.csdn.net/niu_gao
然而理想太豐滿,現實不鳥你。有幾個人能有如此共產主義思想與精力把自己的每一個activity都搞成像系統的打電話發短信這樣的app?大部分activity都是內部使用的。每一個都被搞得非常獨立太費勁了。尤其是app內部的activity之間共享數據時更麻煩,按其原則應把數據放到intent的附加數據中,以startActivityForResult()啟動下一個activity。而且在onActivityResult()中接收下一個activity返回的數據,然而假設搞成全局靜態數據的話多省事?
這樣的設計是不是太過分了?你能夠殺死與前臺app無關的activity或進程,但你怎麽能殺死前臺app中的activity呢?與其讓系統謀殺它還不如讓程序猿自己去殺它。再說了假設系統內存連一個app的正常執行都維持不住了,那是不是這個app設計得太差了?
另一個更混亂之極的情況:最新的android系統中提倡導航欄(難道是要跟蘋果學,省掉一個鍵?),於是在導航欄中就有了返回button。可是當從Activity A中啟動B。然後在B的導航欄上點返回button返回A時(在manifest文件裏將A指定為B的爸爸),實際上A已經不是原來的A了,而是又一次創建了一個。這事是不是太扯蛋了?這樣的情況下A中的onActivityResult()是永遠不會被執行!所以要註意,點導航欄上的返回button與點設備的返回鍵。其效果是不同的,不同的。不同的。。
。扯蛋的事情說三遍!
還有。android的開發文檔中明白說假設activity中開了後臺線程,應該在onDestroy中關閉它。
好吧,一般一個app都由多個頁面導航完畢操作流程,也就是說開多線程的activity在隱藏和顯示之間切換時要不停地開關開關開關多線程?
那有沒有辦法解決問題呢?有!能夠利用另一個功能獨立。自我圓滿的組件:service。利用service做後臺事務,activity在顯隱之間就不會影響到後臺任務了,但又要做activity與service之間的通訊,好麻煩。
但有解決的方法總比沒有強!
還沒完,由於這樣的設計原則帶來了更混亂的activity生命周期管理問題!看一下這個圖,activity的生命周期多麽恐怖。
還有這個圖:
(關於Activity的生命周期。詳見: http://blog.csdn.net/niu_gao/article/details/7101178)
CSDN博客:http://blog.csdn.net/niu_gao
復雜就算了,更操蛋的是不一致性!本來我們以為onStop()一定相應onStart(),誰知道半路殺出個onRestart()。onStart()之後還不算執行狀態,還要再來的onResume() 才算。onCreate()事實上並非相應onDestroy(),而是相應onStop(),我X。能夠罵人嗎?
但最最扯蛋的是,假設你要保存activity上控件的狀態,你須要在onPause()中做!有看官說了,不是onPause(),而是onSaveInstanceState()。
是的。實際上是onSaveInstanceState()中,可是onSaveInstanceState()的調用時機是緊跟onPause()的。所以從時機來說與在onPause()中也沒多少差別。這就是為什麽android界面卡卡卡了!骨子裏帶的,無法解決!僅僅要引起onPause()調用,必定會伴隨硬盤(存儲器)操作!也就是再小的activity切換,都會引起硬盤操作!
但事實上在執行一個app的過程中。這樣的操作百分之99是不須要的。由於activity跟本沒有destroy!全部的控件都在內存中保持著它們的狀態呢!為什麽IOS界面順?由於IOS裏沒有這樣操蛋的設計。IOS裏的ViewController與activity非常類似。但卻沒有要求必須保持執行時獨立性。
android如今有抄IOS的地方,比ListView的替代品:RecycleVeiw,其item的重與機制與IOS的UITableView的cell非常類似了,為什麽不把activity的設計也向IOS學一下呢?
另一個扯蛋的設計:就是屏幕旋轉時。activity會被destroy再create。跟據前面所講。能夠知道destroy和create過程中的代價有多大。這個過程中app進程跟本沒有退出,為毛我要在屏幕旋轉過程關閉線程再開啟?為毛我要關掉網絡再重連?而IOS呢?僅僅是通過一個回調方法給出通知。全然不會關掉view controller再重建。當然由於重建activity,android就有了比IOS更牛B的能力:橫屏和豎屏能夠有全然不同的layout。事實上IOS也能夠啊,僅僅要你實現響應屏幕旋轉的回調方法,在當中自己用代碼調整layout即可了。
我覺得android已經認識都是這個錯誤,所以推出了Fragment這個東西。fragment盡管也有生命周期,可是它不會被系統主動殺死,僅僅要它所在的activity不死。它就一直存在,而且事實上你也能夠讓它離開activity依舊活著。而且你也能夠決定fragment的生死,假設你想省內存。你能夠主動幹掉fragment。
有了fragment,你的app能夠僅僅有一個activity,建多個fragment,頁面切換就是fragment間切換。這樣除了屏幕旋轉時。大部分情況下不存在銷毀和重建問題。不信嗎?你能夠看到管理fragment的API中,有將fragment增加後退棧的方法。後退棧與導航欄上的後退button不正好能夠配合寫出高效的向導類型的界面嗎?所以大家以後要多用fragment少用activity。android推出fragment,就是想讓你這樣做,僅僅只是不好意思把自己原來的設計全局否定,打自己的臉吧了。
(要詳細了解fragment,請見:http://blog.csdn.net/niu_gao/article/details/7163263)
以上都是個人偏見,人外有人天外有天。希望有高手來打我的臉。
CSDN博客:http://blog.csdn.net/niu_gao
最後再說一下關於android程序的優化:
- 首先就是按上面所說:多用fragment,少用activity。事實上這一條就夠了。其他的優化都是針對自己應用的邏輯進行特殊的優化,詳細問題詳細分析。
- 其次是用最新的API。新開發包總會帶來一些優化,或提供新的更高效的組件,比方用RecycleView取代ListView和GridView 。
- 再次是能用C和C++就多用C和C++吧。事實上這一條我並不推薦。由於從代碼維護角度講,還是能用java就用java。
但假設你非要優化到極限,那就多用C和C++(喜歡NDK和c++而且基礎非常差的同學能夠增加這個群:*535807023)*。
- 最後,假設你不怕麻煩。就自己處理屏幕旋轉,大體例如以下:
為你的manifest文件裏的activity元素增加屬性:
android:configChanges=“orientation|keyboardHidden”
然後在activity中響應回調方法:
public void onConfigurationChanged (Configuration newConfig)
CSDN博客:http://blog.csdn.net/niu_gao
希望在新的版本號中,andorid重拾進程的概念。讓大家能自由決定是否將activity搞成執行時獨立,進一步向IOS學習,將activity的pause改成“進入後臺”,將resume改成“成為前臺”,除了生命周期中最基本的create和destroy外,其余的該改名改名,該去掉的去掉。如此則它好我們也好,反正是極好的。
對Android的惡意吐槽(勿看,有毒)