Live a simple life

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

          【原創(chuàng)】Eclipse插件開發(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插件開發(fā)或者開發(fā)RCP程序時(shí),使用圖片資源需要的注意事項(xiàng)

          【系統(tǒng)資源】

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

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

          SWT中的圖片資源管理】

                 我們直接看一下SWT中圖片資源類型的定義(org.eclipse.swt.graphics.Image),在類型說明中明確指出了:“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需要的信息。

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

                 我們知道SWTwidget在銷毀的時(shí)候,也會(huì)銷毀子widget,所以,覆寫你自己的Component對(duì)應(yīng)的dispose方法,將你使用的系統(tǒng)資源銷毀。目前,也只能這樣了~_~。如果覺得不滿意,接著看下面的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 ();

                               }

                        }

                        ……

                 }

          看來,SWT并沒有把事情做絕了,還是給開發(fā)者留下一條后路的。Display允許開發(fā)者注冊(cè)一個(gè)自定義線程hookDisplayrelease過程,開發(fā)者可以用如下方式來確保開發(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、 覆寫相應(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)不要過多依賴此方式,因?yàn)楹苋菀自斐稍?/span>Displayrelease之前,已經(jīng)發(fā)生了系統(tǒng)crash的問題。

          JFace中圖片資源管理--ImageDescriptor

                 前面我們已經(jīng)見過SWT中的ImageImageData類型了,在繼續(xù)下面的內(nèi)容之前,我們先看一下在JFace中我們最常用來創(chuàng)建圖片資源的一個(gè)工廠類:ImageDescriptor。在ImageDescriptor的類型說明中告訴我們,有兩種使用ImageDescriptor創(chuàng)建圖片的方式,分別通過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);

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

                 其次來看一下createImage的方式:

                        /**

          *The returnedimagemustbeexplicitlydisposedusingtheimage'sdispose call.Theimagewillnotbeautomaticallygarbagecollected. */

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

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

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

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

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

                

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

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

          首先我們看一下JFace中的資源管理門面類(façade classJFaceResources,我們由它來獲取我們的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ù)管理。通過JFaceResources.getResources利用了前面說的Displayhook銷毀機(jī)制(注意,如果不通過JFaceResources.getResources來獲取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,通過調(diào)用deallocate徹底銷毀資源

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

                       

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

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

          2、            如果通過JFaceResources.getResources來使用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()                               //銷毀資源

          通過對(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過程中,而ResourceManage.dispose已經(jīng)在JFaceResources.getResources方法中被hook到了Display的資源銷毀過程中)。

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

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

                       

          JFaceResources

          +提供hook機(jī)制

          ImageRegistry

          +自己管理部分資源

          ResourceManager

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

                  

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

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

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

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

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

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

          2、 非共享圖片資源請(qǐng)不要交由ImageRegistry托管。對(duì)于一個(gè)僅限于局部使用而且使用并不是十分頻繁的圖片資源,這樣做不會(huì)帶來什么好處,而且,尤其是對(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ī)制吧。上面提到過了,這其實(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來管理圖片資源;并提供顯示的dipose公共接口,負(fù)責(zé)釋放自己管理的圖片資源

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

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

          如何使用:

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

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

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

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

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

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

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

          b)        如果是通過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問題的原因。導(dǎo)致原因有兩種:

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

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

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

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

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

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



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

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

          評(píng)論

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

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

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

          老大 你知道 我導(dǎo)出的RCP項(xiàng)目后,因?yàn)閳D片問題啟動(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();

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

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

          createImage和createResource都是調(diào)用的一個(gè)方法。沒看出createResource是用的緩存機(jī)制呢
          2014-06-30 11:10 | wcy
          主站蜘蛛池模板: 岗巴县| 万安县| 沙洋县| 炉霍县| 资溪县| 泰兴市| 灵武市| 枞阳县| 青神县| 溧水县| 福清市| 宁强县| 咸阳市| 锡林郭勒盟| 巴塘县| 定结县| 扶绥县| 米脂县| 梅州市| 徐汇区| 静乐县| 洛南县| 黄冈市| 肥东县| 博客| 陆良县| 南康市| 望奎县| 同心县| 丽水市| 花莲市| 监利县| 兴隆县| 深圳市| 龙南县| 龙里县| 屯门区| 榆社县| 莲花县| 安溪县| 宣城市|