一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

通過(guò)Glide組件的GIF能力解讀Glide加載資源的過(guò)程

DRXU_gh_019562b ? 來(lái)源:HarmonyOS開(kāi)發(fā)者 ? 作者: HarmonyOS ? 2021-08-20 10:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

HarmonyOS Glide組件是一款非常優(yōu)秀的圖片處理工具,不僅支持多種格式圖片的加載,而且采用磁盤(pán)緩存和內(nèi)存緩存方式實(shí)現(xiàn)圖片的預(yù)加載,同時(shí)還能指定圖片緩存大小,節(jié)省內(nèi)存。本文將通過(guò)介紹Glide組件的GIF能力,來(lái)解讀Glide加載資源的過(guò)程。

通過(guò)以上視頻可以看到,一張網(wǎng)絡(luò)上的GIF圖片已經(jīng)被成功下載,并且展示到Image控件上了。

我們到底做了什么?實(shí)際上核心的代碼就只有這一段而已:

Glide.with(classcontext) .asGif() .load(uri) .into(image);雖說(shuō)只有這簡(jiǎn)簡(jiǎn)單單的一段代碼,但大家可能不知道的是,Glide在背后幫我們默默執(zhí)行了成噸的工作。下面,我們將圍繞著這段簡(jiǎn)單的代碼,來(lái)解讀Glide加載GIF的過(guò)程。

一、加載過(guò)程與數(shù)據(jù)轉(zhuǎn)換

在開(kāi)始解讀Glide加載GIF的過(guò)程之前,先說(shuō)明一下圖片的加載過(guò)程以及圖片加載過(guò)程中的數(shù)據(jù)轉(zhuǎn)換,便于后面對(duì)整個(gè)過(guò)程的理解。如下所示,是GIF的加載過(guò)程:

10fddf72-00ed-11ec-9bcf-12bb97331649.png

如下所示,是GIF加載過(guò)程中的數(shù)據(jù)轉(zhuǎn)換:

113d68ae-00ed-11ec-9bcf-12bb97331649.png

1、load狀態(tài)傳入的model類(lèi)型

2、request狀態(tài)獲取的數(shù)據(jù)類(lèi)型

3、原數(shù)據(jù)經(jīng)過(guò)decoder和transcode之后的數(shù)據(jù)類(lèi)型

4、transformation變換

5、animation加載動(dòng)畫(huà)實(shí)現(xiàn)

二、Glide.With()

with()方法是Glide類(lèi)中的一組靜態(tài)方法,用于獲取RequestManager對(duì)象。Glide.with(Context)流程如下所示:

115d9a2a-00ed-11ec-9bcf-12bb97331649.png

1.通過(guò)Glide.get(context)初始化Glide2.通過(guò)GlideBuilder初始化各項(xiàng)配置3.返回requestManagerRetriever對(duì)象4.調(diào)用RequestManagerRetriever中的get方法,通過(guò)RequestManagerFactory中的build()方法創(chuàng)建并返回了RequestManager,用于管理Glide的請(qǐng)求。

三、Glide.asGif()

通過(guò)asGif()方法,規(guī)定了最后資源轉(zhuǎn)化類(lèi)型為 GifDrawable。如果加載的資源不是GIF,則將操作失敗。這里需要注意的是如果加載的是GIF文件,即使沒(méi)有使用asGif()方法,但只要配合DraweeView使用,最終解析還是會(huì)走GIF流程。如果用戶(hù)希望解析的GIF顯示為一張單幀圖片,那么一定要在asBitmap ()方法中聲明需求,讓Glide知道需要的僅僅是一張單幀圖片而非GIF。

四、Glide.load()

load()方法用于創(chuàng)建一個(gè)目標(biāo)為Drawable的圖片加載請(qǐng)求,傳入需要加載的資源(String,URL,URI等)。由于with()方法返回的是一個(gè)RequestManager對(duì)象,那么很容易就能想到,load()方法是在RequestManager類(lèi)當(dāng)中。通過(guò)調(diào)用asDrawable()方法,創(chuàng)建一個(gè)目標(biāo)為Drawable的圖片加載請(qǐng)求RequestBuilder。load方法比較簡(jiǎn)單,流程也比較清晰,主要是保存用戶(hù)傳入的參數(shù),包括load傳入的model和RequestOption構(gòu)建的參數(shù)都會(huì)被記錄保存,用于后續(xù)構(gòu)建Request使用。如下所示:

116cf5e2-00ed-11ec-9bcf-12bb97331649.png

五、Glide.into()

如果說(shuō)前面都是在準(zhǔn)備開(kāi)胃小菜的話(huà),那么現(xiàn)在終于要進(jìn)入主菜了,因?yàn)閕nto()方法是整個(gè)Glide圖片加載流程中邏輯最復(fù)雜的地方,into()方法的作用是在子線(xiàn)程中網(wǎng)絡(luò)請(qǐng)求解析圖片,并回到主線(xiàn)程中繪制圖片。由于into()過(guò)程非常復(fù)雜,所以我們將這部分拆分為三個(gè)小節(jié)進(jìn)行講解。

1.資源加載Into()方法從load()創(chuàng)建的圖片加載請(qǐng)求RequestBuilder開(kāi)始。資源加載過(guò)程中,通過(guò)onSizeReady()函數(shù)獲取image控件的寬和高。如果已知控件寬、高則直接進(jìn)入onSizeReady函數(shù)執(zhí)行后續(xù)任務(wù)。如果控件寬、高未知,則會(huì)在ViewTarget中進(jìn)行監(jiān)聽(tīng)回調(diào),待控件擁有寬高之后再執(zhí)行onSizeReady函數(shù)和后續(xù)任務(wù)。

119dac0a-00ed-11ec-9bcf-12bb97331649.png

進(jìn)入engine.load函數(shù)后。首先通過(guò)loadFromMemory()函數(shù),加載activeResource中的緩存資源,如果activeResource沒(méi)有找到資源,則會(huì)通過(guò)loadFromLruCache()方法,到LruCache緩存中尋找資源。如果通過(guò)以上方法都沒(méi)有找到緩存資源,則會(huì)開(kāi)啟新的任務(wù)進(jìn)行加載。在waitForExistingOrStartNewJob()方法中創(chuàng)建EngineJob和DecodeJob,然后通過(guò)EngineJob執(zhí)行DecodeJob,解析任務(wù)。如下圖所示:

11e7551c-00ed-11ec-9bcf-12bb97331649.png

2.資源解析

完成資源加載之后,Glide會(huì)進(jìn)入資源解析,通過(guò)decodeResourceWithList()方法獲取對(duì)應(yīng)的解析器。代碼如下所示

private Resource《ResourceType》 decodeResourceWithList( DataRewinder《DataType》 rewinder,int width,int height,Options options,List《Throwable》 exceptions) throws GlideException { Resource《ResourceType》 result = null; for (int i = 0, size = decoders.size(); i 《 size; i++) { // 循環(huán)去獲取對(duì)應(yīng)的解析器 ResourceDecoder《DataType, ResourceType》 decoder = decoders.get(i); try { DataType data = rewinder.rewindAndGet(); if (decoder.handles(data, options)) { data = rewinder.rewindAndGet(); result = decoder.decode(data, width, height, options); } } catch (IOException | RuntimeException | OutOfMemoryError e) { } } return result;}

然后通過(guò)DataType、ResourceType來(lái)尋找具體實(shí)現(xiàn)類(lèi),發(fā)現(xiàn)byteBufferGifDecoder的decode才是真正的執(zhí)行者。

/* GIFs */.append( Registry.BUCKET_GIF, InputStream.class, GifDrawable.class, new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))ByteBufferGifDecoder byteBufferGifDecoder = new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);

下面是ByteBufferGifDecoder的資源解析過(guò)程,解析完成后會(huì)生成一個(gè)GifDrawable回調(diào)資源。

// 生成GifDecoder GIF的解析工作是GifDecoder承擔(dān)的 GifDecoder gifDecoder = gifDecoderFactory.build(provider, header, byteBuffer, sampleSize); gifDecoder.setDefaultBitmapConfig(config); gifDecoder.advance(); PixelMap firstFrame = gifDecoder.getNextFrame(); // 此處生成 gifDrawable GifDrawable gifDrawable = new GifDrawable(context, gifDecoder, unitTransformation, width, height, firstFrame); return new GifDrawableResource(gifDrawable);

如果成功獲取resource就執(zhí)行回調(diào)通知,onResourceReady()用于將圖片顯示到DraweeView上。

public void onResourceReady(@NotNull Z resource, @Nullable Transition《? super Z》 transition) { if (transition == null || !transition.transition(resource, this)) { setResourceInternal(resource); } else { maybeUpdateAnimatable(resource); }}

如果resource繼承了Animatable,就會(huì)觸發(fā)animatable.start()進(jìn)行GIF的加載和繪制。

private void maybeUpdateAnimatable(@Nullable Z resource) { if (resource instanceof Animatable) { animatable = (Animatable) resource; // GIFDrawable繼承了Animatable所以接下來(lái)GIF流程查看GIFDrawable.java animatable.start(); } else { animatable = null; }}

3.GIF加載和繪制GIF的加載和繪制就是通過(guò)將GIF解析成一張張的單幀圖片,然后再將單幀圖片循環(huán)不停地繪制到canvas上,從而實(shí)現(xiàn)動(dòng)畫(huà)效果。GIF加載和繪制的序列圖如下:

11f461ee-00ed-11ec-9bcf-12bb97331649.png

3.1GIF加載Glide 加載 GIF 的原理就是將GIF 解碼成多張圖片進(jìn)行無(wú)限輪播,每幀切換都是一次圖片加載請(qǐng)求,當(dāng)加載到新的一幀數(shù)據(jù)時(shí)會(huì)對(duì)舊的一幀數(shù)據(jù)進(jìn)行清除,然后再繼續(xù)下一幀數(shù)據(jù)的加載請(qǐng)求,以此類(lèi)推。在GIF加載和繪制的序列圖中可以看到,ImageViewTarget中的onResourceReady觸發(fā)onStart() =》realStart()=》startRunning()。當(dāng)GIF為單張圖片的時(shí)候就直接繪制。當(dāng)GIF為多張圖片就先加載第一張,然后注冊(cè)frameLoader的回調(diào)。

private void startRunning() { if (state.frameLoader.getFrameCount() == 1) { invalidateSelf(); } else if (!isRunning) { isRunning = true; state.frameLoader.subscribe(this); invalidateSelf(); }else{ } } // 注冊(cè)frameLoader的回調(diào) void subscribe(FrameCallback frameCallback) { boolean start = callbacks.isEmpty(); callbacks.add(frameCallback); if (start) { start(); } }到這里,就是整個(gè)GIF加載的關(guān)鍵了,通過(guò)loadNextFrame加載GIF的下一幀。

private void loadNextFrame() { isLoadPending = true; // 獲取解析器當(dāng)前幀到下一幀的延遲時(shí)間 int delay = gifDecoder.getNextDelay(); // 獲取系統(tǒng)當(dāng)前時(shí)間+延時(shí)時(shí)間 long targetTime = SystemClock.uptimeMillis() + delay; // 將GIF的當(dāng)前幀往后+1 gifDecoder.advance(); // 創(chuàng)建出DelayTarget任務(wù) next = new DelayTarget(handler, gifDecoder.getCurrentFrameIndex(), targetTime); // 啟動(dòng)DelayTarget requestBuilder.apply(signatureOf(getFrameSignature())).load(gifDecoder).into(next); }

然后進(jìn)入DelayTarget類(lèi)中執(zhí)行onSourceReady()方法,使用EventHandler將PixelMap的resource傳到主線(xiàn)程上,用于定時(shí)發(fā)送解析好的資源。

public void onResourceReady( PixelMap resource, @Nullable Transition《? super PixelMap》 transition) { this.resource = resource; InnerEvent innerEvent = InnerEvent.get(FrameLoaderCallback.MSG_DELAY, this); // 使用handler發(fā)送消息,此處會(huì)將解析好的資源定時(shí)發(fā)送FrameLoaderCallback handler.sendTimingEvent(innerEvent, targetTime); }FrameLoaderCallback是EventHandler的實(shí)現(xiàn)類(lèi),用于接收EventHandler發(fā)送過(guò)來(lái)的任務(wù),并觸發(fā)onFrameReady函數(shù)。

private class FrameLoaderCallback extends EventHandler{ static final int MSG_DELAY = 1; static final int MSG_CLEAR = 2; @Synthetic FrameLoaderCallback() { super(EventRunner.getMainEventRunner()); } @Override protected void processEvent(InnerEvent event) { if (event.eventId == MSG_DELAY) { DelayTarget target = (DelayTarget) event.object // 接收到消息,觸發(fā)onFrameReady函數(shù) onFrameReady(target); return; } else if (event.eventId == MSG_CLEAR) { DelayTarget target = (DelayTarget) event.object; requestManager.clear(target); } return; } }當(dāng)上一幀加載完成后, GifFrameLoader類(lèi)中的onFrameReady(target)方法觸發(fā)繪制的回調(diào)操作,然后進(jìn)入加載GIF的下一幀。同時(shí),會(huì)通過(guò)FrameLoaderCallback.MSG_CLEAR對(duì)舊的一幀數(shù)據(jù)進(jìn)行清除。清除完后再次通過(guò)loadNextFrame()加載下一幀,實(shí)現(xiàn)了GIF循環(huán)不停去加載下一幀的這個(gè)流程,直到加載完整個(gè)GIF。

void onFrameReady(DelayTarget delayTarget) { // 觸發(fā)了 GifDrawable.java的繪制回調(diào)操作 if (delayTarget.getResource() != null) { recycleFirstFrame(); DelayTarget previous = current; current = delayTarget; for (int i = callbacks.size() - 1; i 》= 0; i--) { FrameCallback cb = callbacks.get(i); // 注冊(cè)在GifFrameLoader的GifDrawable會(huì)接收onFrameReady回調(diào)通知 cb.onFrameReady(); } if (previous != null) { // 這里將上一個(gè)target給清理了 InnerEvent innerEvent = InnerEvent.get(FrameLoaderCallback.MSG_CLEAR, previous); handler.sendEvent(innerEvent); } } // 加載下一幀,構(gòu)成了gif的循環(huán)不停的地去執(zhí)行這個(gè)流程 loadNextFrame(); }3.2GIF繪制GIF繪制,就是將解析后的圖片通過(guò)invalidateSelf()方法通知DraweeView進(jìn)行重繪。在繪制過(guò)程中invalideDraweeView通過(guò)調(diào)用GifDrawable的drawToCanvas()方法將圖片繪制到Canvas上。GifDrawable類(lèi)中的onFrameReady()調(diào)用的invalidateSelf()函數(shù)用于執(zhí)行繪制任務(wù)

public void onFrameReady() { // 如果沒(méi)有找到Callback的實(shí)現(xiàn)控件就停止繪制最后一幀 if (findCallback() == null) { stop(); invalidateSelf(); return; } // 執(zhí)行繪制流程 invalidateSelf(); if (getFrameIndex() == getFrameCount() - 1) { // 循環(huán)次數(shù)計(jì)數(shù) loopCount++; } // 非無(wú)限循環(huán)并且達(dá)到設(shè)置最大值停止gif if (maxLoopCount != LOOP_FOREVER && loopCount 》= maxLoopCount) { stop(); } }public void invalidateSelf(){ final Callback callback = getHmCallback(); if(callback!=null){ // 這里的callback就是注冊(cè)Callback函數(shù)的組件,此處是DraweeView callback.invalidateDrawable(this); }else{ }}通過(guò)調(diào)用setImageElement(((RootShapeElement) resource))方法,實(shí)現(xiàn)Callback接口。

protected void setResource(@Nullable Element resource) { if(resource instanceof PixelMapElement) { view.setPixelMap(((PixelMapElement) resource).getPixelMap()); }else if(resource instanceof RootShapeElement){ view.setImageElement(((RootShapeElement) resource)); } }public void setImageElement(Element element) { if(element == null){ // 如果設(shè)置的內(nèi)容為null 則去刷新圖片并且清空之前的東西 invalidate(); return; } super.setImageElement(element); element.setCallback(this::onChange); if(element instanceof RootShapeElement){ // 將組件注冊(cè)到RootShapeElement中 ((RootShapeElement) element).setHmCallback(this); } }最后通過(guò)drawToCanvas()方法生成空白PixelMap交給GifDrawable繪制,并根據(jù)scaleMode()方法重新設(shè)置最后生成圖像的位置。

private void init(Context context) { setBindStateChangedListener(this); addDrawTask(this::drawToCanvas); setTouchEventListener(this::onTouchEvent); } private void drawToCanvas(Component component, Canvas canvas) { if(getImageElement() instanceof RootShapeElement){ RootShapeElement rootShapeElement = (RootShapeElement) getImageElement(); int rw = rootShapeElement.getIntrinsicWidth(); int rh = rootShapeElement.getIntrinsicHeight(); int cw = component.getWidth(); int ch = component.getHeight(); PixelMap.InitializationOptions opts = new PixelMap.InitializationOptions(); opts.size = new Size(rw, rh); opts.pixelFormat = PixelFormat.ARGB_8888; opts.editable = true; PixelMap gifmap = PixelMap.create(opts); // 生成空白PixelMap交給GifDrawable繪制 applyDrawToCanvas(gifmap); RectFloat src = new RectFloat(0,0,cw,ch); // 根據(jù)scaleMode重新設(shè)置最后生成圖像的位置 RectFloat dst = scaleTypeFixed(gifmap,component); PixelMapHolder pixelMapHolder = new PixelMapHolder(gifmap); canvas.drawPixelMapHolderRect(pixelMapHolder, src, dst, getGifDrawPaint()); } }private void applyDrawToCanvas(PixelMap targetBitmap){ BITMAP_DRAWABLE_LOCK.lock(); try { Canvas canvasRootShape = new Canvas(new Texture(targetBitmap)); // 將canvas交給RootShapeElement,gifDrawable會(huì)調(diào)用RootShapeElement的drawToCanvas 進(jìn)行繪制 getImageElement().drawToCanvas(canvasRootShape); clear(canvasRootShape); } finally { BITMAP_DRAWABLE_LOCK.unlock(); } }至此,整個(gè)GIF的流程就走了一遍。

六、課題延伸

因?yàn)镚IF加載過(guò)程其實(shí)是無(wú)限循環(huán)加載單張圖片的過(guò)程,其實(shí)對(duì)系統(tǒng)的性能消耗還是非常大的。所以在使用GIF的時(shí)候,一定要堅(jiān)持用完之后及時(shí)釋放資源。在這里因?yàn)?a target="_blank">HarmonyOS的生命周期和Android有所不同,所以在DraweeView開(kāi)放了stopGif()方法,當(dāng)你的GIF不打算用之后,請(qǐng)務(wù)必先調(diào)用stopGif(),防止內(nèi)存泄露。

重要提示:

1、目前必須配合DraweeView使用GIF。

2、如果Glide使用了生命周期較長(zhǎng)的上下文,例如applicationContext,則在GIF頁(yè)面結(jié)束時(shí)調(diào)用繪制視圖的stopGif方法停止Glide,以減少資源浪費(fèi)。

3.如果您想使用Glid的GIF能力,但原生Image不支持此功能,因?yàn)镮mage和Element是獨(dú)立的,不能使用Element重繪。要支持GIF,您需要自定義Image。具體可以參考DraweeView的實(shí)現(xiàn)

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3125

    瀏覽量

    75272
  • GIF
    GIF
    +關(guān)注

    關(guān)注

    0

    文章

    24

    瀏覽量

    6827
  • HarmonyOS
    +關(guān)注

    關(guān)注

    80

    文章

    2126

    瀏覽量

    33089

原文標(biāo)題:淺談HarmonyOS Glide組件的GIF能力

文章出處:【微信號(hào):gh_019562b5fb4b,微信公眾號(hào):gh_019562b5fb4b】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何監(jiān)聽(tīng)組件再次顯示的事件?

    不同,組件是沒(méi)有每次顯示都能觸發(fā)的onPageShow這個(gè)生命周期的,但是實(shí)際上,自定義組件也會(huì)有這方面的需求。 我們來(lái)看一下這樣的場(chǎng)景: 項(xiàng)目的主頁(yè)面Index.ets,使用Tabs來(lái)加載4個(gè)子
    發(fā)表于 06-30 18:02

    如何實(shí)現(xiàn)組件截圖 -- componentSnapshot

    截圖”,否則會(huì)和build的過(guò)程相沖突,導(dǎo)致無(wú)法完整截圖。另外,經(jīng)過(guò)測(cè)試,在預(yù)覽器中是不支持的,需要在真機(jī)或者模擬器中實(shí)現(xiàn)。 我在通過(guò)這個(gè)功能對(duì)顯示證書(shū)的Stack組件去進(jìn)行截圖后,還需要將其保存
    發(fā)表于 06-30 17:45

    LoadingProgress組件的使用##HarmonyOS應(yīng)用開(kāi)發(fā)##

    ? ?在應(yīng)用開(kāi)發(fā)的過(guò)程中,經(jīng)常有需要表示“加載中”或者“請(qǐng)等待”的這么一個(gè)狀態(tài)提示,我原來(lái)的做法是會(huì)通過(guò)找一張gif圖片來(lái)表示這一狀態(tài),但是如果使用
    的頭像 發(fā)表于 06-30 17:26 ?165次閱讀

    當(dāng)IM設(shè)備顯示“過(guò)載導(dǎo)致界面無(wú)法加載”時(shí),該如何處理?

    當(dāng) IM 設(shè)備屏幕顯示 “過(guò)載導(dǎo)致界面無(wú)法加載” 時(shí),通常伴隨設(shè)備運(yùn)行異響、指示燈異常閃爍等現(xiàn)象。IM 設(shè)備的過(guò)載保護(hù)機(jī)制通過(guò)傳感器實(shí)時(shí)監(jiān)測(cè)設(shè)備運(yùn)行狀態(tài),一旦檢測(cè)到電流過(guò)載、溫度超標(biāo)或系統(tǒng)資源占用率
    的頭像 發(fā)表于 06-28 11:34 ?225次閱讀

    HarmonyOS NEXT應(yīng)用元服務(wù)布局優(yōu)化長(zhǎng)列表使用懶加載組件復(fù)用

    現(xiàn)BuildLazyItem的耗時(shí),通過(guò)組件復(fù)用能力,可以減少滑動(dòng)過(guò)程中的組件創(chuàng)建耗時(shí),而組件復(fù)
    發(fā)表于 06-27 16:08

    HarmonyOS NEXT應(yīng)用元服務(wù)布局合理使用布局組件

    布局。 List既具備線(xiàn)性布局的特點(diǎn),同時(shí)支持懶加載和滑動(dòng)的能力。 Grid/GridItem提供了宮格布局的能力,同時(shí)也支持懶加載和滑動(dòng)能力
    發(fā)表于 06-20 15:48

    鴻蒙5開(kāi)發(fā)寶藏案例分享---Swiper組件性能優(yōu)化實(shí)戰(zhàn)

    ) { loadImageAsync(targetIndex + 2); // 提前加載后面第2頁(yè) } }) 子組件優(yōu)化 :檢查資源是否已預(yù)加載 @Component struct
    發(fā)表于 06-12 17:53

    HarmonyOS優(yōu)化應(yīng)用預(yù)置圖片資源加載耗時(shí)問(wèn)題性能優(yōu)化

    表: 通過(guò)表中數(shù)據(jù)可以知道,開(kāi)啟紋理壓縮后內(nèi)存的占用從598965KB下降到了165015KB167723KB,圖片加載占用內(nèi)存的大小降低。 2.開(kāi)銷(xiāo) 使用紋理壓縮時(shí),由于在編譯過(guò)程中進(jìn)行預(yù)置圖片的轉(zhuǎn)換
    發(fā)表于 05-29 16:11

    UIAbility組件生命周期介紹

    UIAbility組件生命周期 概述 當(dāng)用戶(hù)打開(kāi)、切換和返回到對(duì)應(yīng)應(yīng)用時(shí),應(yīng)用中的UIAbility實(shí)例會(huì)在其生命周期的不同狀態(tài)之間轉(zhuǎn)換。UIAbility類(lèi)提供了一系列回調(diào),通過(guò)這些回調(diào)可以
    發(fā)表于 05-16 08:28

    UIAbility組件基本用法說(shuō)明

    的啟動(dòng)頁(yè)面 應(yīng)用中的UIAbility在啟動(dòng)過(guò)程中,需要指定啟動(dòng)頁(yè)面,否則應(yīng)用啟動(dòng)后會(huì)因?yàn)闆](méi)有默認(rèn)加載頁(yè)面而導(dǎo)致白屏??梢栽赨IAbility的onWindowStageCreate()生命周期回調(diào)中
    發(fā)表于 05-16 06:32

    「極速探索HarmonyOS NEXT 」閱讀體驗(yàn)】+Web組件

    的Web頁(yè)面中的鏈接時(shí),Web組件會(huì)自動(dòng)加載新頁(yè)面中的資源,并將當(dāng)前顯示的頁(yè)面替換為新頁(yè)面。這樣,可以確保原始 Web 頁(yè)面中的鏈接導(dǎo)航交互正常,并為用戶(hù)提供流暢的瀏覽體驗(yàn)。 Button
    發(fā)表于 03-10 10:39

    解決HarmonyOS應(yīng)用中Image組件白塊問(wèn)題的有效方案

    在HarmonyOS應(yīng)用開(kāi)發(fā)過(guò)程中,通過(guò)Image組件加載網(wǎng)絡(luò)圖片時(shí),通常會(huì)經(jīng)歷四個(gè)關(guān)鍵階段:組件創(chuàng)建、圖片
    的頭像 發(fā)表于 02-17 10:08 ?1126次閱讀
    解決HarmonyOS應(yīng)用中Image<b class='flag-5'>組件</b>白塊問(wèn)題的有效方案

    EE-240: ADSP-BF533 Blackfin加載過(guò)程

    電子發(fā)燒友網(wǎng)站提供《EE-240: ADSP-BF533 Blackfin加載過(guò)程.pdf》資料免費(fèi)下載
    發(fā)表于 01-05 10:00 ?0次下載
    EE-240: ADSP-BF533 Blackfin<b class='flag-5'>加載</b><b class='flag-5'>過(guò)程</b>

    如何提高TLV61046A在啟動(dòng)時(shí)的加載能力

    電子發(fā)燒友網(wǎng)站提供《如何提高TLV61046A在啟動(dòng)時(shí)的加載能力.pdf》資料免費(fèi)下載
    發(fā)表于 09-25 11:34 ?1次下載
    如何提高TLV61046A在啟動(dòng)時(shí)的<b class='flag-5'>加載</b><b class='flag-5'>能力</b>

    OMAPL138/C6748 ROM引導(dǎo)加載程序資源和常見(jiàn)問(wèn)題解答

    電子發(fā)燒友網(wǎng)站提供《OMAPL138/C6748 ROM引導(dǎo)加載程序資源和常見(jiàn)問(wèn)題解答.pdf》資料免費(fèi)下載
    發(fā)表于 09-04 09:31 ?0次下載
    OMAPL138/C6748 ROM引導(dǎo)<b class='flag-5'>加載</b>程序<b class='flag-5'>資源</b>和常見(jiàn)問(wèn)題解答