在 Android 系統(tǒng)中,系統(tǒng)進(jìn)程和非系統(tǒng)進(jìn)程在獲取窗口(Window)方面有一些重要的區(qū)別。下面是它們的主要區(qū)別及實(shí)現(xiàn)方式:
系統(tǒng)進(jìn)程與非系統(tǒng)進(jìn)程獲取窗口的區(qū)別
1、權(quán)限控制:
系統(tǒng)進(jìn)程:系統(tǒng)進(jìn)程擁有較高的權(quán)限,可以直接創(chuàng)建和管理系統(tǒng)級(jí)別的窗口。例如,系統(tǒng)的狀態(tài)欄、通知欄等都是由系統(tǒng)進(jìn)程控制的。
非系統(tǒng)進(jìn)程:普通應(yīng)用進(jìn)程沒(méi)有系統(tǒng)級(jí)別的權(quán)限,通常只能創(chuàng)建應(yīng)用級(jí)別的窗口。為了在系統(tǒng)中創(chuàng)建覆蓋其他應(yīng)用的窗口,非系統(tǒng)進(jìn)程必須獲取 SYSTEM_ALERT_WINDOW 權(quán)限,這個(gè)權(quán)限需要用戶(hù)在設(shè)置中顯式授權(quán)。
2、窗口類(lèi)型:
系統(tǒng)進(jìn)程:可以創(chuàng)建系統(tǒng)類(lèi)型的窗口,如 TYPE_SYSTEM_ALERT 或 TYPE_SYSTEM_OVERLAY,這些窗口能覆蓋其他應(yīng)用,甚至覆蓋在鎖屏界面上。
非系統(tǒng)進(jìn)程:通常只能創(chuàng)建應(yīng)用級(jí)別的窗口,如 TYPE_APPLICATION_OVERLAY(從 Android 8.0 開(kāi)始)或者 TYPE_PHONE(較舊的類(lèi)型,適用于通話(huà)界面)。這些窗口可以覆蓋在其他應(yīng)用窗口之上,但需要特殊權(quán)限,并且有一定的限制。
3、實(shí)現(xiàn)方式:
系統(tǒng)進(jìn)程:通常在系統(tǒng)層面通過(guò) WindowManagerService 直接創(chuàng)建和管理窗口,不需要用戶(hù)的權(quán)限授權(quán)。
非系統(tǒng)進(jìn)程:通過(guò) WindowManager 服務(wù)創(chuàng)建窗口,需要用戶(hù)授權(quán)相應(yīng)的權(quán)限(如 SYSTEM_ALERT_WINDOW),并且在實(shí)現(xiàn)時(shí)需要考慮應(yīng)用的安全性和用戶(hù)體驗(yàn)。
安卓開(kāi)發(fā)者常用的創(chuàng)建窗口的方法
1、使用 WindowManager:
創(chuàng)建窗口:通過(guò) WindowManager 可以創(chuàng)建窗口,窗口的類(lèi)型(如 TYPE_APPLICATION_OVERLAY)決定了窗口的行為和權(quán)限要求。
示例代碼:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
View view = LayoutInflater.from(this).inflate(R.layout.overlay_layout, null);
windowManager.addView(view, params);
2、通過(guò) Service 創(chuàng)建窗口:
步驟:
在 Service 中使用 WindowManager 創(chuàng)建窗口。
需要在 AndroidManifest.xml 中聲明 SYSTEM_ALERT_WINDOW 權(quán)限。
在應(yīng)用設(shè)置中請(qǐng)求用戶(hù)授權(quán) SYSTEM_ALERT_WINDOW 權(quán)限。
示例代碼:
public class OverlayService extends Service {
private WindowManager windowManager;
private View overlayView;
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
overlayView = LayoutInflater.from(this).inflate(R.layout.overlay_layout, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
windowManager.addView(overlayView, params);
}
@Override
public void onDestroy() {
super.onDestroy();
if (overlayView != null) {
windowManager.removeView(overlayView);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
總結(jié)
系統(tǒng)進(jìn)程可以創(chuàng)建系統(tǒng)級(jí)別的窗口,并且無(wú)需額外權(quán)限,但控制范圍較大。
非系統(tǒng)進(jìn)程創(chuàng)建窗口需要額外的權(quán)限,并且通常只能創(chuàng)建應(yīng)用級(jí)別的窗口。
創(chuàng)建窗口的方法包括使用 WindowManager 和在 Service 中進(jìn)行窗口管理。