国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Android】VirtualDisplay創(chuàng)建流程及原理

這篇具有很好參考價值的文章主要介紹了【Android】VirtualDisplay創(chuàng)建流程及原理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Android VirtualDisplay創(chuàng)建流程及原理

  • Android DisplayManager提供了createVirtualDisplay接口,用于創(chuàng)建虛擬屏。虛擬屏可用于錄屏(網(wǎng)上很多資料說這個功能),分屏幕(比如一塊很長的屏幕,通過虛擬屏分出不同的區(qū)域)等等。

創(chuàng)建VirtualDisplay

  • DisplayManager中的函數(shù)原型如下。后兩個Hide的API,只有平臺的應(yīng)用才可以使用。
// frameworks/base/core/java/android/hardware/display/DisplayManager.java
public VirtualDisplay createVirtualDisplay(@NonNull String name,
		int width, int height, int densityDpi, @Nullable Surface surface, int flags) {
}

public VirtualDisplay createVirtualDisplay(@NonNull String name,
		int width, int height, int densityDpi, @Nullable Surface surface, int flags,
		@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
}
/** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
		@NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
		int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
		@Nullable String uniqueId) {
}
/** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
		@NonNull VirtualDisplayConfig virtualDisplayConfig,
		@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
}
  • 補充一點,MediaProjection中也提供了 createVirtualDisplay這個接口,實際上也是通過調(diào)用DisplayManager實現(xiàn)的功能。

// frameworks/base/media/java/android/media/projection/MediaProjection.java
    public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
        DisplayManager dm = mContext.getSystemService(DisplayManager.class);
        // 調(diào)用DisplayManager的接口
        return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler);
    }
  • 創(chuàng)建VirtualDisplay時,需要傳入Surface。**VirtualDisplay上要繪制的內(nèi)容,實際是通過傳入的Surface顯示出來的。**比如在主屏(根據(jù)物理屏,分配邏輯Display)上創(chuàng)建了一個SurfaceView,通過把這個SurfaceView傳給VirtualDisplay。那么VirtualDisplay的 內(nèi)容,實際上是在主屏的SurfaceView上顯示的。下面是一段Android原生的例子。
// frameworks/base/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
private Display createVirtualDisplay() {
	final String displayName = "NavVirtualDisplay";
	final DisplayInfo displayInfo = new DisplayInfo();
	mContext.getDisplay().getDisplayInfo(displayInfo);

	final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);

	// 創(chuàng)建ImageReader,通過它得到一張Surface
	mReader = ImageReader.newInstance(displayInfo.logicalWidth,
			displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);

	assertNotNull("ImageReader must not be null", mReader);

	// 創(chuàng)建虛擬屏,傳入Surface。
	mVirtualDisplay = displayManager.createVirtualDisplay(displayName, displayInfo.logicalWidth,
			displayInfo.logicalHeight, displayInfo.logicalDensityDpi, mReader.getSurface(),
			0 /*flags*/);

	assertNotNull("virtual display must not be null", mVirtualDisplay);

	waitForDisplayReady(mVirtualDisplay.getDisplay().getDisplayId());

	return mVirtualDisplay.getDisplay();
}
  • 上面的例子中創(chuàng)建虛擬屏,返回Display(實際上是VirtualDislay)對象。有了Display對象,我們就可以將View綁定到這個虛擬的Display上了(綁定網(wǎng)上方法比較多可自行搜索)。關(guān)于Surface的創(chuàng)建,有很多種方法,比如通過SurfaceContron+Buffer這種方式也可以。
  • VituralDisplay創(chuàng)建時,需要提供flag。其值定義如下,可通過 “或”將flag組合。
 
    public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0;

    public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 1 << 1;

    public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2;

    public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 1 << 3;

    public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 1 << 4;

    public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;

    public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;

    public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;

    public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;

    public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;

    public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;

    public static final int VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP = 1 << 11;
  • DisplayManager公開的接口中,有VirtualDisplay.Callback ,提供了其狀態(tài)的回調(diào)。
    public static abstract class Callback {
        /**
         * Called when the virtual display video projection has been
         * paused by the system or when the surface has been detached
         * by the application by calling setSurface(null).
         * The surface will not receive any more buffers while paused.
         */
         public void onPaused() { }

        /**
         * Called when the virtual display video projection has been
         * resumed after having been paused.
         */
         public void onResumed() { }

        /**
         * Called when the virtual display video projection has been
         * stopped by the system.  It will no longer receive frames
         * and it will never be resumed.  It is still the responsibility
         * of the application to release() the virtual display.
         */
        public void onStopped() { }
    }

VirtualDisplay原理

  • 關(guān)于VirtualDisplay的實現(xiàn)原理,主要從AndroidFramework角度進行分析。
    createvirtualdisplay,Android,android,virtualdisplay,虛擬屏,原理,surface
// /frameworks/base/core/java/android/hardware/display/DisplayManager.java
public VirtualDisplay createVirtualDisplay(@NonNull String name,
		int width, int height, int densityDpi, @Nullable Surface surface, int flags) {
	return createVirtualDisplay(name, width, height, densityDpi, surface, flags, null, null);
}

public VirtualDisplay createVirtualDisplay(@NonNull String name,
		int width, int height, int densityDpi, @Nullable Surface surface, int flags,
		@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
	final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
			height, densityDpi);
	builder.setFlags(flags);
	if (surface != null) {
		builder.setSurface(surface);
	}
	return createVirtualDisplay(null /* projection */, builder.build(), callback, handler);
}

// TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
/** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
		@NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
		int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
		@Nullable String uniqueId) {
	final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
			height, densityDpi);
	builder.setFlags(flags);
	if (uniqueId != null) {
		builder.setUniqueId(uniqueId);
	}
	if (surface != null) {
		builder.setSurface(surface);
	}
	return createVirtualDisplay(projection, builder.build(), callback, handler);
}

/** @hide */
public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
		@NonNull VirtualDisplayConfig virtualDisplayConfig,
		@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
	// 走的這里,會調(diào)用到DisplayManagerGlobal中。
	return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
			handler);
}
  • DisplayManagerGlobal調(diào)用DMS(DisplayManagerService)服務(wù)創(chuàng)建虛擬屏,得到DMS返回的DisplayID后,通過DisplayID在Client端創(chuàng)建了VirtualDisplay對象。
// /frameworks/base/core/java/android/hardware/display/DisplayManager.java
public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
		@NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
		Handler handler) {
	VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
	// 從MediaProjection過來的調(diào)用,這個地方非空。
	IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
	int displayId;
	try {
		// 告知DMS創(chuàng)建虛擬屏,并返回DisplayID
		displayId = mDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper,
				projectionToken, context.getPackageName());
	} catch (RemoteException ex) {
		throw ex.rethrowFromSystemServer();
	}
	if (displayId < 0) {
		Log.e(TAG, "Could not create virtual display: " + virtualDisplayConfig.getName());
		return null;
	}
	
	// 通過DisplayID,取得Display對象信息(也是調(diào)用DMS得到的)
	Display display = getRealDisplay(displayId);
	if (display == null) {
		Log.wtf(TAG, "Could not obtain display info for newly created "
				+ "virtual display: " + virtualDisplayConfig.getName());
		try {
			// 創(chuàng)建失敗,需要釋放
			mDm.releaseVirtualDisplay(callbackWrapper);
		} catch (RemoteException ex) {
			throw ex.rethrowFromSystemServer();
		}
		return null;
	}
	
	// 創(chuàng)建VirtualDisplay
	return new VirtualDisplay(this, display, callbackWrapper,
			virtualDisplayConfig.getSurface());
}
  • DisplayManagerService(DMS)中創(chuàng)建DisplayDevice并添加到Device列表中管理
// /frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
@Override // Binder call
public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
		IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
		
	// 檢查uid與包名,是否相符。
	final int callingUid = Binder.getCallingUid();
	if (!validatePackageName(callingUid, packageName)) {
		throw new SecurityException("packageName must match the calling uid");
	}
	if (callback == null) {
		throw new IllegalArgumentException("appToken must not be null");
	}
	if (virtualDisplayConfig == null) {
		throw new IllegalArgumentException("virtualDisplayConfig must not be null");
	}
	//  拿到client端傳過來的surface對象
	final Surface surface = virtualDisplayConfig.getSurface();
	int flags = virtualDisplayConfig.getFlags();

	if (surface != null && surface.isSingleBuffered()) {
		throw new IllegalArgumentException("Surface can't be single-buffered");
	}

	// 下面開始針對Flag,做一些邏輯判斷。
	if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
		flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;

		// Public displays can't be allowed to show content when locked.
		if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
			throw new IllegalArgumentException(
					"Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
		}
	}
	if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
		flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
	}
	if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
		flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
	}

	if (projection != null) {
		try {
			if (!getProjectionService().isValidMediaProjection(projection)) {
				throw new SecurityException("Invalid media projection");
			}
			flags = projection.applyVirtualDisplayFlags(flags);
		} catch (RemoteException e) {
			throw new SecurityException("unable to validate media projection or flags");
		}
	}

	if (callingUid != Process.SYSTEM_UID &&
			(flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
		if (!canProjectVideo(projection)) {
			throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
					+ "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
					+ "MediaProjection token in order to create a screen sharing virtual "
					+ "display.");
		}
	}
	if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
		if (!canProjectSecureVideo(projection)) {
			throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
					+ "or an appropriate MediaProjection token to create a "
					+ "secure virtual display.");
		}
	}

	if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
		if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
			EventLog.writeEvent(0x534e4554, "162627132", callingUid,
					"Attempt to create a trusted display without holding permission!");
			throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
					+ "create a trusted virtual display.");
		}
	}

	if (callingUid != Process.SYSTEM_UID
			&& (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
		if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
			throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
					+ "create a virtual display which is not in the default DisplayGroup.");
		}
	}

	if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
		flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
	}

	// Sometimes users can have sensitive information in system decoration windows. An app
	// could create a virtual display with system decorations support and read the user info
	// from the surface.
	// We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
	// to trusted virtual displays.
	final int trustedDisplayWithSysDecorFlag =
			(VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
					| VIRTUAL_DISPLAY_FLAG_TRUSTED);
	if ((flags & trustedDisplayWithSysDecorFlag)
			== VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
			&& !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
			throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
	}

	final long token = Binder.clearCallingIdentity();
	try {
		// 調(diào)用內(nèi)部實現(xiàn)
		return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
				surface, flags, virtualDisplayConfig);
	} finally {
		Binder.restoreCallingIdentity(token);
	}
}

// /frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
		IMediaProjection projection, int callingUid, String packageName, Surface surface,
		int flags, VirtualDisplayConfig virtualDisplayConfig) {
	synchronized (mSyncRoot) {
		if (mVirtualDisplayAdapter == null) {
			Slog.w(TAG, "Rejecting request to create private virtual display "
					+ "because the virtual display adapter is not available.");
			return -1;
		}
		// 為虛擬屏創(chuàng)建Device(告知surfaceflinger創(chuàng)建Display)
		DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
				callback, projection, callingUid, packageName, surface, flags,
				virtualDisplayConfig);
		if (device == null) {
			return -1;
		}

		// 發(fā)送添加Device通知,這里比較重要
		mDisplayDeviceRepo.onDisplayDeviceEvent(device,
				DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
		// 檢查Display是否創(chuàng)建成功
		final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
		if (display != null) {
			return display.getDisplayIdLocked();
		}

		// Something weird happened and the logical display was not created.
		Slog.w(TAG, "Rejecting request to create virtual display "
				+ "because the logical display was not created.");
		mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
		mDisplayDeviceRepo.onDisplayDeviceEvent(device,
				DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
	}
	return -1;
}
  • 接下來DMS開始調(diào)用SurfaceFlinger的接口,創(chuàng)建Display。并將Display放入自身的List中管理。
// /frameworks/base/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
		IMediaProjection projection, int ownerUid, String ownerPackageName, Surface surface,
		int flags, VirtualDisplayConfig virtualDisplayConfig) {
	String name = virtualDisplayConfig.getName();
	// VIRTUAL_DISPLAY_FLAG_SECURE 的用途,是判斷是否為安全的Display,這個參數(shù)會告知SurfaceFlinger
	boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
	IBinder appToken = callback.asBinder();
	// 調(diào)用SurfaceFligner創(chuàng)建Display(Display的type是virtual)
	IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure);
	final String baseUniqueId =
			UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
	final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
	String uniqueId = virtualDisplayConfig.getUniqueId();
	if (uniqueId == null) {
		uniqueId = baseUniqueId + uniqueIndex;
	} else {
		uniqueId = UNIQUE_ID_PREFIX + ownerPackageName + ":" + uniqueId;
	}
	// 通過SurfaceFligner返回的displayToken,創(chuàng)建Device對象
	VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
			ownerUid, ownerPackageName, surface, flags, new Callback(callback, mHandler),
			uniqueId, uniqueIndex, virtualDisplayConfig);
	//  放到虛擬屏的List中管理。
	mVirtualDisplayDevices.put(appToken, device);

	try {
		if (projection != null) {
			projection.registerCallback(new MediaProjectionCallback(appToken));
		}
		appToken.linkToDeath(device, 0);
	} catch (RemoteException ex) {
		mVirtualDisplayDevices.remove(appToken);
		device.destroyLocked(false);
		return null;
	}

	// Return the display device without actually sending the event indicating
	// that it was added.  The caller will handle it.
	return device;
}

// /frameworks/base/services/core/java/com/android/server/display/DisplayDeviceRepository.java
//  mDisplayDeviceRepo.onDisplayDeviceEvent(device,
//				DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 
// 這段代碼,會調(diào)用到下面的函數(shù)中。
private void handleDisplayDeviceAdded(DisplayDevice device) {
	synchronized (mSyncRoot) {
		DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
		if (mDisplayDevices.contains(device)) {
			Slog.w(TAG, "Attempted to add already added display device: " + info);
			return;
		}
		Slog.i(TAG, "Display device added: " + info);
		device.mDebugLastLoggedDeviceInfo = info;
		// 需要是將Device(就是上面創(chuàng)建的虛擬屏幕Device)放入到DMS的管理list
		mDisplayDevices.add(device);
		// 通知Device添加,會調(diào)用到LogicalDisplayMappe的handleDisplayDeviceAddedLocked中。
		sendEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
	}
}
// /frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
	DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
	// Internal Displays need to have additional initialization.
	// This initializes a default dynamic display layout for INTERNAL
	// devices, which is used as a fallback in case no static layout definitions
	// exist or cannot be loaded.
	if (deviceInfo.type == Display.TYPE_INTERNAL) {
		initializeInternalDisplayDeviceLocked(device);
	}

	// Create a logical display for the new display device
	LogicalDisplay display = createNewLogicalDisplayLocked(
			device, Layout.assignDisplayIdLocked(false /*isDefault*/));

	// 刷新布局和display配置
	applyLayoutLocked();
	updateLogicalDisplaysLocked();
}
  • 虛擬屏幕的創(chuàng)建,Client端通過Surface告知的DisplayID,創(chuàng)建VirtualDisplay對象。通過DisplayID,與DMS打交道。DMS服務(wù)端,通過SurfaceFlinger創(chuàng)建虛擬屏,拿到SurfaceFligner的DisplayToken,然后通過它創(chuàng)建VirtualDisplayDevice + LogicalDisplay來管理虛擬屏幕。
    createvirtualdisplay,Android,android,virtualdisplay,虛擬屏,原理,surface
如何上屏?
  • 創(chuàng)建虛擬屏幕的時候,會傳入了一張Surface(比如綁定主屏的一張Buffer)。虛擬屏通過這張Surface拿到Surface對應(yīng)的Buffer,將上屏內(nèi)容繪制到這個Buffer上,然后提交到畫面流水線上(SurfaceFlinger)。通過SurfaceFlinger將這個這個Buffer最終由SurfaceFlinger描畫并顯示到Surface所在那張Display上(根據(jù)VirtualDisplay位置去顯示。)
    createvirtualdisplay,Android,android,virtualdisplay,虛擬屏,原理,surface

文章來源地址http://www.zghlxwxcb.cn/news/detail-763489.html

到了這里,關(guān)于【Android】VirtualDisplay創(chuàng)建流程及原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android Activity的啟動流程(Android-10)

    Android Activity的啟動流程(Android-10)

    在Android開發(fā)中,我們經(jīng)常會用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的啟動流程嗎?今天就專門講一下最基礎(chǔ)的startActivity(Intent)看一下Activity的啟動流程,同時由于Launcher的啟動后續(xù)和這里基本類似,就記錄在一起。注意本章都是基于Android-10來講解的。

    2024年01月17日
    瀏覽(21)
  • Android WiFi 開啟流程(基于Android S)

    Android WiFi 開啟流程(基于Android S)

    本文介紹Android S上WiFi的Enable流程 WifiManager.setWifiEnabled(true) - WifiServiceImpl.enable(pkgName, true) - setWifiEnabledInternal(packageName, enable, callingUid, callingPid, isPrivileged) - mSettingsStore.handleWifiToggled(enable) - Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state) mPersistWifiState = state 記下wifi狀態(tài) - mActiveMod

    2024年02月03日
    瀏覽(17)
  • android源碼學(xué)習(xí)- APP啟動流程(android12源碼)

    android源碼學(xué)習(xí)- APP啟動流程(android12源碼)

    百度一搜能找到很多講APP啟動流程的,但是往往要么就是太老舊(還是基于android6去分析的),要么就是不全(往往只講了整個流程的一小部分)。所以我結(jié)合網(wǎng)上現(xiàn)有的文章,以及源碼的閱讀和調(diào)試,耗費了3整天的時間,力求寫出一篇最完整,最詳細,最通俗易懂的文章,

    2024年02月11日
    瀏覽(21)
  • 靈魂畫師,Android繪制流程——Android高級UI(1)

    靈魂畫師,Android繪制流程——Android高級UI(1)

    繪制流程從何而起 Activity 的界面結(jié)構(gòu)在哪里開始形成 繪制流程如何運轉(zhuǎn)起來 接下來我們就一個個目標來 conquer。 我們一說到 繪制流程 ,就會想到或是聽過 onMeasure 、 onLayout 、 onDraw 這三個方法,但是有沒想過為什么我們開啟一個App或是點開一個Activity,就會觸發(fā)這一系列流

    2024年04月17日
    瀏覽(31)
  • android支付寶接入流程

    android支付寶接入流程

    接入APP支付能力前,開發(fā)者需要完成以下前置步驟。 本文檔展示了如何從零開始,使用支付寶開放平臺服務(wù)端 SDK 快速接入App支付產(chǎn)品,完成與支付寶對接的部分。 要在您的應(yīng)用中接入支付寶 App 支付能力,您需要登錄支付寶開放平臺open.alipay.com),在開發(fā)者中心中創(chuàng)建您的

    2024年04月13日
    瀏覽(13)
  • Android啟動流程優(yōu)化 中篇

    本文鏈接:https://blog.csdn.net/feather_wch/article/details/131587046 1、我們可以優(yōu)化部分 Application構(gòu)建到主界面onWindowFocusChanged 2、啟動方式(官方) 冷啟動 熱啟動 溫啟動 3、怎么樣算是卡頓? 卡頓:2-5-8原則 2秒以內(nèi):流程 2-5秒:可以接受 5-8秒:有些卡頓 8秒以上:非??D,沒辦法接

    2024年02月12日
    瀏覽(37)
  • Android系統(tǒng)啟動流程概覽

    Boot Rom —— Bootloader —— Linux Kernel —— init進程 —— Zygote進程(dalvik/ art)—— systemServer —— Apps init 進程是Linux系統(tǒng)中,用戶空間啟動的第一個進程。 創(chuàng)建并掛載一些文件目錄 啟動屬性服務(wù) 解析 init.rc 配置文件,啟動 Zygote 進程 掛載 seLinux 文件目錄,創(chuàng)建seLinux,加載

    2024年02月06日
    瀏覽(22)
  • Android 畫面顯示流程二

    Android 畫面顯示流程二

    BufferQueue BufferQueue要解決的是生產(chǎn)者的同步問題,應(yīng)用程序生產(chǎn)畫面,SurfaceFlinger消費畫面,SurfaceFlinger生產(chǎn)畫面而HWCService消費畫面。用來存儲這些畫面的存儲區(qū)我們稱其為幀緩沖區(qū)buffer,下面我們以應(yīng)用程序作為生產(chǎn)者,SurfaceFlinger作為消費者為例來了解一下BufferQueue的內(nèi)部設(shè)

    2024年02月13日
    瀏覽(20)
  • 詳解Android 關(guān)機/重啟流程

    詳解Android 關(guān)機/重啟流程

    本文基于android 10源碼分析 手機長按power鍵,彈出關(guān)機提示對話框,如下圖 一、先來看長按power鍵執(zhí)行的流程。 開機后先注冊輸入監(jiān)聽事件,長按power鍵時,kernel層會發(fā)出一個事件上來,該事件最終被InputDispatcher.handleReceiveCallback監(jiān)聽到 事件是從native層的InputDispatcher.cpp一直傳到

    2024年02月04日
    瀏覽(18)
  • Android:啟動流程

    Android:啟動流程

    第一步:啟動電源以及系統(tǒng)啟動 當電源按下,引導(dǎo)芯片代碼開始從預(yù)定義的地方(固化在ROM)開始執(zhí)行。加載引導(dǎo)程序到RAM,然后 執(zhí)行 第二步:引導(dǎo)程序 引導(dǎo)程序是在Android操作系統(tǒng)開始運行前的一個小程序。引導(dǎo)程序是運行的第一個程序,因此它是針 對特定的主板與芯片的

    2023年04月16日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包