<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Live a simple life

    沉默(zhu_xing@live.cn)
    隨筆 - 48, 文章 - 0, 評(píng)論 - 132, 引用 - 0
    數(shù)據(jù)加載中……

    【原創(chuàng)】Eclipse插件開(kāi)發(fā):Eclipse中的圖片資源管理

     

    Eclipse中的圖片資源管理

                                                             朱興(zhu_xing@live.cn

    【概述】

    在本文中,將討論如下內(nèi)容:

    1、 系統(tǒng)資源,為后面討論圖片資源做一鋪墊

    2、 SWT中的圖片資源管理

    3、 Display hook銷毀機(jī)制,JFace中圖片資源管理的重要基礎(chǔ)

    4、 JFace中的ImageDescriptor

    5、 JFace中的圖片資源管理(ImageRegistry

    6、 JFace中圖片資源管理ImageRegistry所適用的場(chǎng)景和使用規(guī)則

    7、 Eclipse中插件share images機(jī)制

    8、 Eclipse插件開(kāi)發(fā)或者開(kāi)發(fā)RCP程序時(shí),使用圖片資源需要的注意事項(xiàng)

    【系統(tǒng)資源】

    眾所周知,Java開(kāi)發(fā)人員在使用SWT/JFACE的時(shí)候,并不能借助于Java內(nèi)置的垃圾回收機(jī)制來(lái)徹底完成系統(tǒng)資源的清理(Java虛擬機(jī)只能幫助我們釋放虛擬機(jī)內(nèi)存中的系統(tǒng)資源句柄引用對(duì)象)。在SWT中系統(tǒng)資源對(duì)象的定級(jí)類型是org.eclipse.swt.graphics.Resource,在類型明確說(shuō)明了“Resources created by the application must be disposed”,這也讓我們想起了關(guān)于Image使用的一句名言“誰(shuí)創(chuàng)建,誰(shuí)負(fù)責(zé)”,當(dāng)然,這個(gè)原則也同樣適用于其他類型的系統(tǒng)資源。

    我們之所以如此關(guān)注系統(tǒng)資源的使用,尤其是臭名昭著的圖片資源,主要是因?yàn)槲覀兣铝讼到y(tǒng)資源泄漏引起的系統(tǒng)crash的問(wèn)題。例如org.eclipse.swt.SWTError: No more handles異常有可能在我們?cè)噲D創(chuàng)建圖片資源的時(shí)候發(fā)生,這說(shuō)明當(dāng)前系統(tǒng)句柄已經(jīng)不足,造成這個(gè)問(wèn)題的罪魁禍?zhǔn)桩?dāng)然是我們寫(xiě)代碼的人。

    SWT中的圖片資源管理】

           我們直接看一下SWT中圖片資源類型的定義(org.eclipse.swt.graphics.Image),在類型說(shuō)明中明確指出了:“Application code must explicitly invoke the Image.dispose() method to release the operating system resources managed by each instance when those instances are no longer required”。我們?cè)倏匆幌铝硗庖粋€(gè)我們熟悉的類型org.eclipse.swt.graphics.ImageData,我們可以將其看作是Image對(duì)應(yīng)的元數(shù)據(jù)模型對(duì)象,描述了具體創(chuàng)建Image需要的信息。

           通過(guò)上面的說(shuō)明,我們發(fā)現(xiàn)SWT唯一告訴我們的是:自己創(chuàng)建的圖片資源,自己負(fù)責(zé)去銷毀,通過(guò)調(diào)用Image.dispose()。那我們?cè)谑褂?/span>SWT的時(shí)候,應(yīng)該如何釋放圖片資源呢?

           我們知道SWTwidget在銷毀的時(shí)候,也會(huì)銷毀子widget,所以,覆寫(xiě)你自己的Component對(duì)應(yīng)的dispose方法,將你使用的系統(tǒng)資源銷毀。目前,也只能這樣了~_~。如果覺(jué)得不滿意,接著看下面的Display hook銷毀機(jī)制。

    Display hook銷毀機(jī)制】

           Display device中,我們看了如下一個(gè)hook接口:

           /**

         *Causesthe<code>run()</code>methodoftherunnableto

         *beinvokedbytheuser-interfacethreadjustbeforethe

         *receiverisdisposed. 

         */

           public void disposeExec (Runnable runnable) {

                  //注冊(cè)用戶自定義runnable,在display release的時(shí)候回調(diào)此runnable

                  runnable注冊(cè)到disposeList

           }

           disposeList中的線程會(huì)在display release的時(shí)候被調(diào)用,如下:

           /**

     *Releasesanyinternalresourcesbacktotheoperating

     *systemandclearsallfieldsexceptthedevicehandle.

    */

           protected void release () {

                  ……

                  //會(huì)執(zhí)行用戶注冊(cè)的銷毀線程

                  if (disposeList != null) {

                         for (int i=0; i<disposeList.length; i++) {

                                if (disposeList [i] != null) disposeList [i].run ();

                         }

                  }

                  ……

           }

    看來(lái),SWT并沒(méi)有把事情做絕了,還是給開(kāi)發(fā)者留下一條后路的。Display允許開(kāi)發(fā)者注冊(cè)一個(gè)自定義線程hookDisplayrelease過(guò)程,開(kāi)發(fā)者可以用如下方式來(lái)確保開(kāi)發(fā)者使用的系統(tǒng)資源在Display release的時(shí)候被銷毀:

    display.disposeExec(new Runnable() {

                  public void run() {

                         //銷毀系統(tǒng)資源的邏輯代碼

                         image.dispose();

                         …….

                  }    

           });

    以上方式其實(shí)也是JFace中圖片資源管理(ImageRegistryResourceManager)能夠確保Display release的時(shí)候能夠徹底釋放被ImageRegistry托管的圖片資源。

           到這里回顧一下,SWT中資源釋放的途徑吧:

    1、 覆寫(xiě)相應(yīng)Component對(duì)應(yīng)的dispose方法。這有別于Displayhook機(jī)制,因?yàn)槠淠軌蛟?/span>Display運(yùn)行期間(未被release之前)就釋放掉系統(tǒng)資源,最好的方式。

    2、 利用Displayhook機(jī)制,確保在Displayrelease的時(shí)候能夠銷毀資源。注意,請(qǐng)不要過(guò)多依賴此方式,因?yàn)楹苋菀自斐稍?/span>Displayrelease之前,已經(jīng)發(fā)生了系統(tǒng)crash的問(wèn)題。

    JFace中圖片資源管理--ImageDescriptor

           前面我們已經(jīng)見(jiàn)過(guò)SWT中的ImageImageData類型了,在繼續(xù)下面的內(nèi)容之前,我們先看一下在JFace中我們最常用來(lái)創(chuàng)建圖片資源的一個(gè)工廠類:ImageDescriptor。在ImageDescriptor的類型說(shuō)明中告訴我們,有兩種使用ImageDescriptor創(chuàng)建圖片的方式,分別通過(guò)createImagecreateResource接口,“There are two ways to get an Image from an ImageDescriptor. The method createImage will always return a new Image which must be disposed by the caller. Alternatively, createResource() returns a shared Image. When the caller is done with an image obtained from createResource, they must call destroyResource() rather than disposing the Image directly.”。分析如下:

    首先看一下createResource方式,ImageDescriptor是一種DeviceResourceDescriptor,后者的對(duì)外操作如下:

            /**

           *Createstheresourcedescribedbythisdescriptor

             */

            public abstract Object createResource(Device device) throws DeviceResourceException;

            /**

          *Undoeseverythingthatwasdonebyapreviouscalltocreate(...)

             */

            public abstract void destroyResource(Object previouslyCreatedObject);

    這也就是說(shuō),ImageDescriptor提供了createResource / destroyResource接口來(lái)負(fù)責(zé)創(chuàng)建和銷毀Image資源。請(qǐng)注意這邊的一點(diǎn),在孤立使用ImageDescriptor(沒(méi)有配合ResourceRegistry使用,例如ImageRegistry)的時(shí)候,用戶還是要負(fù)責(zé)通過(guò)調(diào)用destroyResource來(lái)釋放創(chuàng)建的資源

           其次來(lái)看一下createImage的方式:

                  /**

    *The returnedimagemustbeexplicitlydisposedusingtheimage'sdispose call.Theimagewillnotbeautomaticallygarbagecollected. */

                  public Image createImage(boolean returnMissingImageOnError, Device device) {}

    這也就是說(shuō),ImageDescriptor提供的createImage的方式,也需要用戶來(lái)顯示的銷毀資源。那createImagecreateResource兩種方式之間的差別是什么呢?稍微分析一下ImageDescriptor的這兩種創(chuàng)建方式的實(shí)現(xiàn),我們就可以看出來(lái)差別:

    1、 createImage每次都創(chuàng)建一個(gè)全新的圖片資源(圖片資源的創(chuàng)建是很耗時(shí)的~_~

    2、 createResource的方式采用了緩存的方式復(fù)用已經(jīng)創(chuàng)建過(guò)的資源,并不是每次都創(chuàng)建一個(gè)全新的資源。這一點(diǎn)雖然帶來(lái)了性能的提高,但是并沒(méi)有解決圖片資源釋放的問(wèn)題,倒是給開(kāi)發(fā)者留下了一種假象,造成了隨便使用ImageDescriptor的問(wèn)題,反而造成了大量的圖片資源(當(dāng)然,更多的是由于調(diào)用createImage的方式造成的,因?yàn)槊看味紕?chuàng)建一個(gè)全新的圖片資源)沒(méi)有釋放。

    到現(xiàn)在為止,我們看到JFace已經(jīng)對(duì)SWT中的圖片資源的管理做了一個(gè)小的補(bǔ)充:提供了ImageDescriptor.createResource的方式,可以利用緩存效果,能夠減少不必要的圖片系統(tǒng)資源創(chuàng)建,而且效率有所提高。關(guān)于如何釋放,可以參考SWT中覆寫(xiě)Component.dispose的方式,例如在label provider使用的圖片資源,可以覆寫(xiě)對(duì)于providerdispose方法,JFace框架會(huì)自動(dòng)調(diào)用。

          

    JFace中圖片資源管理--ImageRegistry & ResourceManager

    下面,我們接著看一下JFace中的ImageRegistry的實(shí)現(xiàn)原理。

    首先我們看一下JFace中的資源管理門(mén)面類(façade classJFaceResources,我們由它來(lái)獲取我們的JFace ImageRegistry

    public static ImageRegistry getImageRegistry() {

         if (imageRegistry == null) {

    imageRegistry = new ImageRegistry(getResources(Display.getCurrent()));

         }

         return imageRegistry;

    }

    public static ResourceManager getResources(final Display toQuery) {

        ResourceManager reg = (ResourceManager)registries.get(toQuery);

        if (reg == null) {

           final DeviceResourceManager mgr = new DeviceResourceManager(toQuery);

             

                   //Display hook了銷毀線程

    toQuery.disposeExec(new Runnable() {

              public void run() {

                 mgr.dispose();

                 registries.remove(toQuery);

              }

    });

        }

        return reg;

    }

    分析了一下ResourceManagerDeviceResourceManager)的實(shí)現(xiàn),我們發(fā)現(xiàn):DeviceResourceManager就是對(duì)DeviceResourceDescriptorImageDescriptor)進(jìn)行了引用計(jì)數(shù)管理。通過(guò)JFaceResources.getResources利用了前面說(shuō)的Displayhook銷毀機(jī)制(注意,如果不通過(guò)JFaceResources.getResources來(lái)獲取ResourceManager,則不會(huì)默認(rèn)享受Displayhook銷毀機(jī)制,需要自己向Display注冊(cè)),確保由被托管ImageDescriptor創(chuàng)建的殘留在系統(tǒng)中的圖片資源在Display release的時(shí)候會(huì)被徹底銷毀。核心方法如下:

    create(DeviceResourceDescriptor descriptor)  

    //如果是首次注冊(cè),創(chuàng)建引用技數(shù),allocate資源并對(duì)資源進(jìn)行緩存

    //如果是已經(jīng)注冊(cè),增加引用技數(shù),直接返回緩存的系統(tǒng)資源

           destroy(DeviceResourceDescriptor descriptor) //

           //如果引用技術(shù)==1,通過(guò)調(diào)用deallocate徹底銷毀資源

           //如果引用技術(shù)>1,削減引用計(jì)數(shù)(系統(tǒng)資源不會(huì)被銷毀)

                 

    那就是說(shuō),如果一個(gè)ImageDescriptorResourceManager托管了,那由它創(chuàng)建的資源(注意:通過(guò)ImageDescriptor.createResource的方式)由兩種銷毀的途徑:

    1、            如果不通過(guò)JFaceResources.getResources的方式,單獨(dú)使用ResourceManager,則只能利用ResourceManager的引用計(jì)數(shù)管理來(lái)銷毀資源(引用計(jì)數(shù)為0時(shí)),通過(guò)顯示調(diào)用ResourceManager.destroy來(lái)削減引用計(jì)數(shù)。

    2、            如果通過(guò)JFaceResources.getResources來(lái)使用ResourceManager,則除了能夠使用到引用計(jì)數(shù)管理資源,同時(shí)也默認(rèn)使用了Displayhook銷毀機(jī)制,JFaceImageRegistry也很好的利用了這一點(diǎn)。

    現(xiàn)在回頭看一下ImageRegistry提供的核心操作,著重分析一下ImageRegistry在利用了ResourceManager對(duì)ImageDescriptor進(jìn)行管理的基礎(chǔ)上,做了那些補(bǔ)充:

    put(String key, Image image)              //注冊(cè)image

    put(String key, ImageDescriptor descriptor) //注冊(cè)descriptor

    Image get(String key)                    //獲取imge

    ImageDescriptor getDescriptor(String key)   //獲取descriptor

    remove(String key)                      //取消注冊(cè)

    dipose()                               //銷毀資源

    通過(guò)對(duì)ImageRegistry簡(jiǎn)要的分析之后,我們的結(jié)論如下:

    1、 如果以put(String key, ImageDescriptor descriptor)的方式注冊(cè),ImageRegistry直接講descriptor委托給ResourceManager委托管理,自己并不承擔(dān)管理任務(wù)。而且,ImageRegistry對(duì)這種方式注冊(cè)的ImageDescriptor所創(chuàng)建的系統(tǒng)圖片資源的銷毀也委托給ResourceManager進(jìn)行,并不是在以上自己的dispose方法中進(jìn)行,而是在ResourceManager.dispose方法中進(jìn)行。

    2、 如果以put(String key, Image image)的方式注冊(cè),ImageRegistry做了部分的補(bǔ)充管理,其將image包裝進(jìn)自己的OriginalImageDescriptorImageRegistry的一個(gè)內(nèi)部類,繼承自ImageDescriptor,對(duì)圖片資源本身增加引用計(jì)數(shù)實(shí)現(xiàn)中,并對(duì)image本身進(jìn)行了引用計(jì)數(shù)管理。同時(shí),對(duì)這種方式注冊(cè)的圖片資源的銷毀是ImageRegistry自己承擔(dān)的,在自身的dispose方法中完成。(注意,在ImageRegistry的構(gòu)造方法中,將ImageRegistry.dispose封裝為一個(gè)runnable注冊(cè)到了ResourceManagedispose過(guò)程中,而ResourceManage.dispose已經(jīng)在JFaceResources.getResources方法中被hook到了Display的資源銷毀過(guò)程中)。

    3、 通過(guò)12的結(jié)論,JFace ImageRegistry對(duì)系統(tǒng)資源的銷毀已經(jīng)做了兩手準(zhǔn)備,

    其并不希望用戶自己來(lái)銷毀資源(無(wú)論是通過(guò)Image.dispose還是ImageDescriptor.destoryResource,或者ImageRegistry.dispose),當(dāng)然,ImageRegistry允許通過(guò)remove接口來(lái)取消注冊(cè)。

                 

    JFaceResources

    +提供hook機(jī)制

    ImageRegistry

    +自己管理部分資源

    ResourceManager

    +管理ImageDescriptor及其創(chuàng)建的資源

            

    ImageRegistry的適用場(chǎng)景和使用規(guī)則】

    通過(guò)上面的實(shí)現(xiàn)原理分析,我們知道ImageRegistry并不歡迎用戶來(lái)過(guò)多地參與圖片資源的釋放過(guò)程,所以ImageRegistry適用于如下場(chǎng)景:

    1、 決定共享和高度復(fù)用的圖片資源。這種資源一般是被使用的特別頻繁,同時(shí),不急于銷毀,只要在Display release的時(shí)候銷毀掉就可以了,所以既可以利用到圖片資源本身緩存的優(yōu)勢(shì)(減少物理創(chuàng)建的次數(shù)),又可以利用其Displayhook銷毀機(jī)制,確保會(huì)被銷毀。

    2、 用戶可以直接使用ImageRegistry(不通過(guò)JFaceResources.getImageRegistry的方式使用),復(fù)用部分ImageRegistry的管理功能,開(kāi)發(fā)自己的緩存策略,但是,要確保自己會(huì)在合適的地方調(diào)用ImageRegistry.dispose方法來(lái)銷毀registryEclipse Workbench中的shared images機(jī)制就用了這一點(diǎn)。

    ImageRegistry的使用規(guī)則如下:

    1、 誰(shuí)創(chuàng)建,誰(shuí)負(fù)責(zé)。具體圖片資源的創(chuàng)建是由ImageRegistry負(fù)責(zé)的,用戶既然托管了,就不應(yīng)該再干預(yù)資源的釋放。而且,注冊(cè)進(jìn)ImageRegistry的資源是共享的,一個(gè)用戶釋放了,會(huì)影響到其他用戶的使用。當(dāng)然,對(duì)于比較熟悉JFace ImageRegistry原理的開(kāi)發(fā)者,可以參與到引用計(jì)數(shù)的管理,通過(guò)這種方式,以安全的、不影響其他用戶使用的方式來(lái)間接參與釋放的過(guò)程。

    2、 非共享圖片資源請(qǐng)不要交由ImageRegistry托管。對(duì)于一個(gè)僅限于局部使用而且使用并不是十分頻繁的圖片資源,這樣做不會(huì)帶來(lái)什么好處,而且,尤其是對(duì)于不能參與到引用計(jì)數(shù)管理的初級(jí)用戶,這樣做反而會(huì)使得一個(gè)本可以馬上釋放的圖片資源反而會(huì)一直占用,直到Display release的時(shí)候才銷毀。

    3、 要投入精力對(duì)ImageRegistrykey值進(jìn)行管理,否則,會(huì)引起混亂。因?yàn)?/span>ImageRegistry本質(zhì)上可以看作Eclipse平臺(tái)中的一個(gè)全局對(duì)象,對(duì)其含有的key列表的管理是再所難免。

    Eclipse中插件share images機(jī)制】

           Eclipse,一個(gè)插件可以暴露(expose)自己的圖片資源,以便提供給需要的插件使用,我們就稱它為插件之間的share images機(jī)制吧。上面提到過(guò)了,這其實(shí)是部分復(fù)用了JFace ImageRegistry的管理機(jī)制。

           如何共享(可以參照Workbench插件的share images實(shí)現(xiàn)):

    1、 按照默認(rèn)約定,創(chuàng)建一個(gè)ISharedImages接口,提供有意義key

    2、 實(shí)現(xiàn)自己創(chuàng)建的ISharedImages接口,并結(jié)合ImageRegistry來(lái)管理圖片資源;并提供顯示的dipose公共接口,負(fù)責(zé)釋放自己管理的圖片資源

    3、 在自己的插件中暴露ISharedImages

    4、 在合適時(shí)機(jī),調(diào)用ISharedImages.dispose來(lái)釋放資源。這個(gè)時(shí)機(jī)一般選擇在Plugin stop的時(shí)候比較合適,當(dāng)然,也可以選擇在其他時(shí)機(jī)。

    如何使用:

    1、 獲取目標(biāo)插件的ISharedImages實(shí)現(xiàn),并通過(guò)ISharedImages提供的key值來(lái)獲取特定的圖片資源。以workbench插件share images為例:

    PlatformUI.getWorkbench().getSharedImages().getImage(key)

    2、暴露圖片資源的插件負(fù)責(zé)圖片資源的創(chuàng)建和銷毀,其他插件不要參與銷毀過(guò)程。換句話說(shuō),還是要遵守誰(shuí)創(chuàng)建、誰(shuí)負(fù)責(zé)的原則。workbench插件share images為例:

    workbench close的時(shí)候,會(huì)間接調(diào)用ISharedImages.dispose()

    Eclipse中使用圖片資源的經(jīng)驗(yàn)總結(jié)】

    1、 堅(jiān)持“誰(shuí)創(chuàng)建,誰(shuí)負(fù)責(zé)”的原則。分為如下:

    a)         如果是用戶自己創(chuàng)建的,請(qǐng)自己釋放。例如通過(guò)覆寫(xiě)Component對(duì)于的dispose方法、通過(guò)覆寫(xiě)label provider對(duì)應(yīng)的dispose方法等等,這對(duì)于一些適用于局部的圖片資源較為適合;當(dāng)然,也可以變態(tài)利用Displayhook釋放機(jī)制(但是,一般對(duì)于長(zhǎng)期使用的資源才會(huì)這樣做!!!)。

    b)        如果是通過(guò)JFaceResources.getImageRegistry的方式使用ImageRegistry時(shí),請(qǐng)不要釋放資源,讓ImageRegistry自己解決。一般使用于比較頻繁使用的全局共享圖片資源,例如想保持風(fēng)格統(tǒng)一的圖片資源等。

    c)        如果是使用了IShareImages的機(jī)制,請(qǐng)?zhí)峁﹫D片資源的插件自己負(fù)責(zé)釋放。如何使用這種機(jī)制,最好參照eclipse中已有的實(shí)現(xiàn),保持風(fēng)格統(tǒng)一,“有樣學(xué)樣”吧。

    2、 正確認(rèn)識(shí)系統(tǒng)資源泄漏引起的crash問(wèn)題的原因。導(dǎo)致原因有兩種:

    a)         首先,是沒(méi)有釋放,導(dǎo)致泄漏。請(qǐng)參照上面的“誰(shuí)創(chuàng)建,誰(shuí)負(fù)責(zé)”的原則。

    b)        其次,是釋放的過(guò)晚,導(dǎo)致積累過(guò)多。例如本來(lái)應(yīng)該立即釋放的資源,反而通過(guò)ImageRegistry進(jìn)行了托管,同時(shí)有沒(méi)有控制引用計(jì)數(shù)的管理,導(dǎo)致到了Display release的時(shí)候才釋放資源。同樣道理,本來(lái)不需要暴露給其他插件貢獻(xiàn)的圖片資源,反而暴露了,導(dǎo)致釋放過(guò)完等。

    3、 正確認(rèn)識(shí)系統(tǒng)資源的創(chuàng)建和銷毀所帶來(lái)的時(shí)間消耗,這是從系統(tǒng)性能的角度考慮。例如,可以用ImageDescriptor.createResource的方式替換原始的new Image的方式,減少創(chuàng)建資源過(guò)于頻繁和銷毀資源過(guò)于頻繁所帶來(lái)的時(shí)間占用。對(duì)于需要長(zhǎng)期使用的貢獻(xiàn)資源,可以使用ImageRegistry的方式等等。

    4、 對(duì)于特殊的場(chǎng)景,可以在參考以上原理(例如JFace中的圖片管理的實(shí)現(xiàn)原理分析)的基礎(chǔ)上自己實(shí)現(xiàn)圖片資源的管理策略。這對(duì)團(tuán)隊(duì)開(kāi)發(fā)產(chǎn)品的情況下尤其適用,一方面可以優(yōu)化管理策略,使之更切近團(tuán)隊(duì)?wèi)?yīng)用;再者,可以減少JFace ImageRegsitry使用的復(fù)雜度,并減少誤用。例如,我們可以把插件間share images的機(jī)制看成是對(duì)JFace ImageRegsitry的靈活使用。

    5、 無(wú)論使用那種管理策略(無(wú)論是來(lái)自eclipse還是其他),使用這前一定要仔細(xì)看API說(shuō)明,并簡(jiǎn)要分析一下實(shí)現(xiàn)原理。對(duì)于做上規(guī)模的插件產(chǎn)品/應(yīng)用來(lái)講,畢竟對(duì)圖片這種系統(tǒng)資源的管理太重要了!!!對(duì)于做較為簡(jiǎn)單的開(kāi)發(fā),基本上本著“誰(shuí)創(chuàng)建、誰(shuí)負(fù)責(zé)”的原則,用完之后在自己感覺(jué)合適的地方銷毀掉就可以了,完全可以不去碰JFace中的ImageRegistry那套東東,引來(lái)不必要的負(fù)責(zé)度和復(fù)用,尤其是對(duì)于新手來(lái)說(shuō)。

    PS:文章是昨天趕出來(lái)的,沒(méi)有細(xì)看。有什么錯(cuò)誤之處,歡迎大家指出~_~
       
    附件是本文的word文檔  word格式文檔



    本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請(qǐng)注明出處,謝謝!

    posted on 2008-08-06 10:30 zhuxing 閱讀(3194) 評(píng)論(3)  編輯  收藏 所屬分類: Eclipse Plug-in & OSGI

    評(píng)論

    # re: 【原創(chuàng)】Eclipse插件開(kāi)發(fā):Eclipse中的圖片資源管理  回復(fù)  更多評(píng)論   

    thanks for sharing
    2008-08-07 10:05 | hw

    # re: 【原創(chuàng)】Eclipse插件開(kāi)發(fā):Eclipse中的圖片資源管理  回復(fù)  更多評(píng)論   

    老大 你知道 我導(dǎo)出的RCP項(xiàng)目后,因?yàn)閳D片問(wèn)題啟動(dòng)不了的原因嗎


    java.lang.Exception: Unsupported or unrecognized format
    at cn.edu.jfcs.app.Application.run(Application.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethod(EclipseAppContainer.java:572)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:171)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1173)


    我用的是CacheImage.java 主要是這樣得到圖片
    image = AbstractUIPlugin.imageDescriptorFromPlugin(applicationID, imageName).createImage();

    上面問(wèn)題如何解決啊 有人說(shuō)要用ImageRegistry才行 不太會(huì)用
    2008-08-19 17:19 | appleq

    # re: 【原創(chuàng)】Eclipse插件開(kāi)發(fā):Eclipse中的圖片資源管理  回復(fù)  更多評(píng)論   

    createImage和createResource都是調(diào)用的一個(gè)方法。沒(méi)看出createResource是用的緩存機(jī)制呢
    2014-06-30 11:10 | wcy

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 999久久久免费精品播放| 亚洲成av人片一区二区三区| 日韩免费码中文在线观看| 亚洲大尺码专区影院| 亚洲精品乱码久久久久久按摩| 免费无码又爽又刺激高潮| 在线人成精品免费视频| 丰满人妻一区二区三区免费视频| 亚洲乱码无人区卡1卡2卡3| 亚洲狠狠狠一区二区三区| 亚洲第一极品精品无码久久| xvideos亚洲永久网址| 免费黄色app网站| 欧美大尺寸SUV免费| 99免费在线观看视频| 精品一卡2卡三卡4卡免费视频| 一级成人a免费视频| 免费高清A级毛片在线播放| 亚洲欧美一区二区三区日产| 亚洲一区二区久久| 亚洲第一成年网站大全亚洲| 亚洲国产老鸭窝一区二区三区| 国产精品亚洲成在人线| 伊人婷婷综合缴情亚洲五月| 亚洲AV蜜桃永久无码精品| 免费国产怡红院在线观看| 日本19禁啪啪无遮挡免费动图| 成年免费大片黄在线观看岛国| 99视频全部免费精品全部四虎| 久久久久免费看成人影片| 免费人成网站在线观看不卡 | 免费无码又黄又爽又刺激| 1000部国产成人免费视频| **aaaaa毛片免费| 在线日本高清免费不卡| 最近免费中文字幕高清大全| 最近中文字幕完整版免费高清| 99在线视频免费| 99热在线精品免费全部my| 成人网站免费观看| 国产在线观看免费视频播放器 |