阿里Android開發規範:程式、執行緒與訊息通訊

leeyh發表於2018-03-06

以下內容摘自 阿里巴巴Android開發手冊

我們的目標是:

  • 防患未然,提升質量意識,降低故障率和維護成本;
  • 標準統一,提升協作效率;
  • 追求卓越的工匠精神,打磨精品程式碼。
  • 【強制】必須遵守,違反本約定或將會引起嚴重的後果;
  • 【推薦】儘量遵守,長期遵守有助於系統穩定性和合作效率的提升;
  • 【參考】充分理解,技術意識的引導,是個人學習、團隊溝通、專案合作的方向。

阿里Android開發規範:資原始檔命名與使用規範
阿里Android開發規範:四大基本元件
阿里Android開發規範:UI 與佈局
阿里Android開發規範:程式、執行緒與訊息通訊
阿里Android開發規範:檔案與資料庫
阿里Android開發規範:Bitmap、Drawable 與動畫
阿里Android開發規範:安全與其他

1、【強制】不要通過 Intent 在Android基礎元件之間傳遞大資料(binder transaction快取為 1MB),可能導致OOM。
2、【強制】在 Application 的業務初始化程式碼加入程式判斷,確保只在自己需要的程式初始化。特別是後臺程式減少不必要的業務初始化。
正例:

public class MyApplication extends Application {
	@Override
	public void onCreate() {
		//在所有程式中初始化
		....
		//僅在主程式中初始化
		if (mainProcess) {
			...
		}
		//僅在後臺程式中初始化
		if (bgProcess) {
			...
		}
	}
}
複製程式碼

3、【強制】新建執行緒時,必須通過執行緒池提供(AsyncTask 或者 ThreadPoolExecutor或者其他形式自定義的執行緒池),不允許在應用中自行顯式建立執行緒。 說明: 使用執行緒池的好處是減少在建立和銷燬執行緒上所花的時間以及系統資源的開銷,解決資源不足的問題。如果不使用執行緒池,有可能造成系統建立大量同類執行緒而導致消耗完記憶體或者“過度切換”的問題。另外建立匿名執行緒不便於後續的資源使用分析,對效能分析等會造成困擾。
正例:

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();

ExecutorService executorService = new ThreadPoolExecutor(
	NUMBER_OF_CORES, //corePoolSize:核心執行緒數
	NUMBER_OF_CORES*2, //maximumPoolSize:執行緒池最大執行緒數
	KEEP_ALIVE_TIME, //keepAliveTime:非核心執行緒閒置超時時間
	KEEP_ALIVE_TIME_UNIT, //Unit:非核心執行緒閒置超時時間單位
	taskQueue, //workQueue:任務佇列
	new BackgroundThreadFactory(), //threadFactory:執行緒工廠
	new DefaultRejectedExecutionHandler() //handler:表示當拒絕處理任務時的策略);
//執行任務
executorService.execute(new Runnnable() {
...
});
複製程式碼

反例:

new Thread(new Runnable() {
	@Override
	public void run() {
		//操作語句
		...
	}
}).start();
複製程式碼

擴充套件參考:
blog.mindorks.com/threadpoole…
4、【強制】執行緒池不允許使用 Executors 去建立,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。 說明: Executors 返回的執行緒池物件的弊端如下:

  1. FixedThreadPool 和 SingleThreadPool : 允許的請求佇列長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致 OOM;
  2. CachedThreadPool 和 ScheduledThreadPool : 允許的建立執行緒數量為Integer.MAX_VALUE,可能會建立大量的執行緒,從而導致 OOM。

正例:

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();

ExecutorService executorService = new ThreadPoolExecutor(
	NUMBER_OF_CORES, //corePoolSize
	NUMBER_OF_CORES*2, //maximumPoolSize
	KEEP_ALIVE_TIME, //keepAliveTime
	KEEP_ALIVE_TIME_UNIT, //Unit
	taskQueue, //workQueue
	new BackgroundThreadFactory(), //threadFactory
	new DefaultRejectedExecutionHandler() //handler);
複製程式碼

反例:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
複製程式碼

擴充套件參考: dev.bizo.com/2014/06/cac…
5、【強制】子執行緒中不能更新介面,更新介面必須在主執行緒中進行,網路操作不能在主執行緒中呼叫。
6、【強制】不要在非 UI 執行緒中初始化 ViewStub,否則會返回 null。
7、【推薦】儘量減少不同 APP 之間的程式間通訊及拉起行為。拉起導致佔用系統資源,影響使用者體驗。
8、【推薦】新建執行緒時,定義能識別自己業務的執行緒名稱,便於效能優化和問題排查。
正例:

public class MyThread extends Thread {
	public MyThread(){
		super.setName("ThreadName");
		…
	}
}
複製程式碼

9、【推薦】ThreadPoolExecutor 設定執行緒存活時間(setKeepAliveTime),確保空閒時執行緒能被釋放。 10、【推薦】 禁止在多進 程之間用 SharedPreferences 共享資料 , 雖然可以(MODE_MULTI_PROCESS),但官方已不推薦。
11、【推薦】謹慎使用 Android 的多程式,多程式雖然能夠降低主程式的記憶體壓力,但會遇到如下問題:

  1. 不能實現完全退出所有 Activity 的功能;
  2. 首次進入新啟動程式的頁面時會有延時的現象(有可能黑屏、白屏幾秒,是白屏還是黑屏和新 Activity 的主題有關);
  3. 應用內多程式時,Application 例項化多次,需要考慮各個模組是否都需要在所有程式中初始化;
  4. 多程式間通過 SharedPreferences 共享資料時不穩定。

阿里Android開發規範:資原始檔命名與使用規範
阿里Android開發規範:四大基本元件
阿里Android開發規範:UI 與佈局
阿里Android開發規範:程式、執行緒與訊息通訊
阿里Android開發規範:檔案與資料庫
阿里Android開發規範:Bitmap、Drawable 與動畫
阿里Android開發規範:安全與其他

相關文章