Android Glide使用的詳解

1、在build.gradle中添加依賴(lài):? ??

compile 'com.github.bumptech.glide:glide:3.7.0'

需要support-v4庫(kù)的支持,如果你的項(xiàng)目沒(méi)有support-v4庫(kù)(項(xiàng)目默認(rèn)已經(jīng)添加了),還需要添加support-v4依賴(lài):? ? ?

?compile'com.Android.support:support-v4:23.3.0'

2、然后配置混淆規(guī)則:

-keeppublicclass

?*implements

?com.bumptech.glide.module.GlideModule

-keeppublic

enum?

com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$**

?{

**[] $VALUES;

public *;

?}

其中第一個(gè)混淆規(guī)則表明不混淆所有的GlideModule。

?如果需要的話(huà),還需添加相應(yīng)的權(quán)限:

3、 使用Glide.with(this).load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png").into(imageView);

Glide.with()

使用with(Context context). 使用Application上下文,Glide請(qǐng)求將不受Activity/Fragment生命周期控制。

with(Activity activity).使用Activity作為上下文,Glide的請(qǐng)求會(huì)受到Activity生命周期控制。with(FragmentActivity activity).Glide的請(qǐng)求會(huì)受到FragmentActivity生命周期控制。with(android.app.Fragment fragment).Glide的請(qǐng)求會(huì)受到Fragment 生命周期控制。with(android.support.v4.app.Fragment fragment).Glide的請(qǐng)求會(huì)受到Fragment生命周期控制。

requestManager.load()

使用Glide基本可以load任何可以拿到的媒體資源,如:

?load SD卡資源:load("file://"+ Environment.getExternalStorageDirectory().getPath()+"/test.jpg") load assets資源:load("file:///android_asset/f003.gif") load raw資源:load("Android.resource://com.frank.glide/raw/raw_1")或load("android.resource://com.frank.glide/raw/"+R.raw.raw_1) load drawable資源:load("android.resource://com.frank.glide/drawable/news")或load("android.resource://com.frank.glide/drawable/"+R.drawable.news) load ContentProvider資源:load("content://media/external/images/media/139469") load http資源:load("http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg") load https資源:load(" http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg ")?

當(dāng)然,load不限于String類(lèi)型,還可以:??

?load(Uri uri),load(File file),load(Integer resourceId),load(URL url),load(byte[] model),load(T model),loadFromMediaStore(Uri uri)。?

load的資源也可以是本地視頻,如果想要load網(wǎng)絡(luò)視頻或更高級(jí)的操作可以使用VideoView等其它控件完成。?

而且可以使用自己的ModelLoader進(jìn)行資源加載:

? using(ModelLoadermodelLoader, ClassdataClass),using(final StreamModelLoadermodelLoader),using(StreamByteArrayLoader modelLoader),using(final FileDescriptorModelLoadermodelLoader)。?

返回GenericRequestBuilder實(shí)例。

GenericRequestBuilder使用

GenericRequestBuilder是最頂層的Request Builder,用于處理選項(xiàng)設(shè)置和開(kāi)始一般resource類(lèi)型資源的加載。其中ModelType是指代表資源的類(lèi)型,如"http://img.my.csdn.net/uploads/201508/05/1438760757_3588.jpg"這個(gè)String就代表了一張圖片資源,所以這個(gè)ModelType就是String。DataType是指ModelLoader提供的,可以被ResourceDecoder解碼的數(shù)據(jù)類(lèi)型。ResourceType是指將要加載的resource類(lèi)型。TranscodeType是指已解碼的資源將要被轉(zhuǎn)成的資源類(lèi)型。

1、thumbnail(float sizeMultiplier). 請(qǐng)求給定系數(shù)的縮略圖。如果縮略圖比全尺寸圖先加載完,就顯示縮略圖,否則就不顯示。系數(shù)sizeMultiplier必須在(0,1)之間,可以遞歸調(diào)用該方法。

2、sizeMultiplier(float sizeMultiplier). 在加載資源之前給Target大小設(shè)置系數(shù)。

3、diskCacheStrategy(DiskCacheStrategy strategy).設(shè)置緩存策略。DiskCacheStrategy.SOURCE:緩存原始數(shù)據(jù),DiskCacheStrategy.RESULT:緩存變換(如縮放、裁剪等)后的資源數(shù)據(jù),DiskCacheStrategy.NONE:什么都不緩存,DiskCacheStrategy.ALL:緩存SOURC和RESULT。默認(rèn)采用DiskCacheStrategy.RESULT策略,對(duì)于download only操作要使用DiskCacheStrategy.SOURCE。

4、priority(Priority priority). 指定加載的優(yōu)先級(jí),優(yōu)先級(jí)越高越優(yōu)先加載,但不保證所有圖片都按序加載。枚舉Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL,Priority.LOW。默認(rèn)為Priority.NORMAL。

5、dontAnimate(). 移除所有的動(dòng)畫(huà)。

6、animate(int animationId). 在異步加載資源完成時(shí)會(huì)執(zhí)行該動(dòng)畫(huà)。

7、animate(ViewPropertyAnimation.Animator animator). 在異步加載資源完成時(shí)會(huì)執(zhí)行該動(dòng)畫(huà)。

8、placeholder(int resourceId). 設(shè)置資源加載過(guò)程中的占位Drawable。

9、placeholder(Drawable drawable). 設(shè)置資源加載過(guò)程中的占位Drawable。

10、fallback(int resourceId). 設(shè)置model為空時(shí)要顯示的Drawable。如果沒(méi)設(shè)置fallback,model為空時(shí)將顯示error的Drawable,如果error的Drawable也沒(méi)設(shè)置,就顯示placeholder的Drawable。

11、fallback(Drawable drawable).設(shè)置model為空時(shí)顯示的Drawable。

12、error(int resourceId).設(shè)置load失敗時(shí)顯示的Drawable。

13、error(Drawable drawable).設(shè)置load失敗時(shí)顯示的Drawable。

14、listener(RequestListenerrequestListener). 監(jiān)聽(tīng)資源加載的請(qǐng)求狀態(tài),可以使用兩個(gè)回調(diào):onResourceReady(R resource, T model, Targettarget, boolean isFromMemoryCache, boolean isFirstResource)和onException(Exception e, T model, Target target, boolean isFirstResource),但不要每次請(qǐng)求都使用新的監(jiān)聽(tīng)器,要避免不必要的內(nèi)存申請(qǐng),可以使用單例進(jìn)行統(tǒng)一的異常監(jiān)聽(tīng)和處理。

15、skipMemoryCache(boolean skip). 設(shè)置是否跳過(guò)內(nèi)存緩存,但不保證一定不被緩存(比如請(qǐng)求已經(jīng)在加載資源且沒(méi)設(shè)置跳過(guò)內(nèi)存緩存,這個(gè)資源就會(huì)被緩存在內(nèi)存中)。

16、override(int width, int height). 重新設(shè)置Target的寬高值(單位為pixel)。

17、into(Y target).設(shè)置資源將被加載到的Target。

18、into(ImageView view). 設(shè)置資源將被加載到的ImageView。取消該ImageView之前所有的加載并釋放資源。

19、into(int width, int height). 后臺(tái)線(xiàn)程加載時(shí)要加載資源的寬高值(單位為pixel)。

20、preload(int width, int height). 預(yù)加載resource到緩存中(單位為pixel)。

21、asBitmap(). 無(wú)論資源是不是gif動(dòng)畫(huà),都作為Bitmap對(duì)待。如果是gif動(dòng)畫(huà)會(huì)停在第一幀。

22、asGif().把資源作為GifDrawable對(duì)待。如果資源不是gif動(dòng)畫(huà)將會(huì)失敗,會(huì)回調(diào).error()。

4、技巧

?1、禁止內(nèi)存緩存:? ?

?.skipMemoryCache(true)

2、清除內(nèi)存緩存:? ?

?// 必須在UI線(xiàn)程中調(diào)用? ??

Glide.get(context).clearMemory();

3、禁止磁盤(pán)緩存:

? .diskCacheStrategy(DiskCacheStrategy.NONE)

4、清除磁盤(pán)緩存:?

?// 必須在后臺(tái)線(xiàn)程中調(diào)用,建議同時(shí)clearMemory()? Glide.get(applicationContext).clearDiskCache();

5、獲取緩存大小:?

new GetDiskCacheSizeTask(textView).execute(new File(getCacheDir(), DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));11class GetDiskCacheSizeTask extends AsyncTask{

private final TextView resultView;

public GetDiskCacheSizeTask(TextView resultView) {

this.resultView = resultView;

}

@Override

protected void onPreExecute() {

resultView.setText("Calculating...");

}

@Override

protected void onProgressUpdate(Long... values) { /* onPostExecute(values[values.length - 1]); */ }

@Override

protected Long doInBackground(File... dirs) {

try {

long totalSize = 0;

for (File dir : dirs) {

publishProgress(totalSize);

totalSize += calculateSize(dir);

}

return totalSize;

} catch (RuntimeException ex) {

final String message = String.format("Cannot get size of %s: %s", Arrays.toString(dirs), ex);

new Handler(Looper.getMainLooper()).post(new Runnable() {

@Override

public void run() {

resultView.setText("error");

Toast.makeText(resultView.getContext(), message, Toast.LENGTH_LONG).show(); ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?return 0L;

}

@Override

protected void onPostExecute(Long size) {

String sizeText = android.text.format.Formatter.formatFileSize(resultView.getContext(), size);

resultView.setText(sizeText);

}

private static long calculateSize(File dir) {

if (dir == null) return 0;

if (!dir.isDirectory()) return dir.length();

long result = 0;

File[] children = dir.listFiles();

if (children != null)

for (File child : children)

result += calculateSize(child);

return result;}

}

6、指定資源的優(yōu)先加載順序:??

//優(yōu)先加載

? ? ?Glide

? ? ? ? ? ? ?.with(context)

? ? ? ? ? ? ?.load(heroImageUrl)

? ? ? ? ? ? .priority(Priority.HIGH)

? ? ? ? ? ? .into(imageViewHero);

//后加載

? ? ? ?Glide

? ? ? ? ? ? .with(context)

? ? ? ? ? ? .load(itemImageUrl)

? ? ? ? ? ?.priority(Priority.LOW)

? ? ? ? ? ? .into(imageViewItem);

7、先顯示縮略圖,再顯示原圖:? ?

//用原圖的1/10作為縮略圖? ? Glide? ? ? ?

?.with(this) ? ? ? ? ? ? ? ?.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") ? ? ? ? .thumbnail(0.1f)? ? ? ? .into(iv_0);? ? //用其它圖片作為縮略圖 ? ? ? ?DrawableRequestBuilderthumbnailRequest = Glide

.with(this)

.load(R.drawable.news);

Glide.with(this)

.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")

.thumbnail(thumbnailRequest)

.into(iv_0);

8、對(duì)圖片進(jìn)行裁剪、模糊、濾鏡等處理:

?推薦使用獨(dú)立的圖片處理庫(kù):wasabeef/glide-transformations,使用也很簡(jiǎn)單:?

?? compile 'jp.wasabeef:glide-transformations:2.0.0'

之后我們就可以使用GenericRequestBuilder或其子類(lèi)的transform()或bitmapTransform()方法設(shè)置圖片轉(zhuǎn)換了:? ?

?//圓形裁剪? ? Glide.with(this)? ? ? ? .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") ? ? ? ? ? ? .bitmapTransform(new CropCircleTransformation(this)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??.into(iv_0); ?

? //圓角處理 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??Glide.with(this)? ? ? ? .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")? ? ? ? .bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.into(iv_0); ??

?//灰度處理? ?

?Glide.with(this)? ? ? ? .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")? ? ? ? .bitmapTransform(new GrayscaleTransformation(this)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??.into(iv_0); ? ?

//其它變換...

5、 Glide有哪些“坑”?

1、ImageView的setTag問(wèn)題 問(wèn)題描述: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??如果使用Glide的into(imageView)為ImageView設(shè)置圖片的同時(shí)使用ImageView的setTag(final Object tag)方法,將會(huì)導(dǎo)致java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting異常。因?yàn)镚lide的ViewTarget中通過(guò)view.setTag(tag)和view.getTag()標(biāo)記請(qǐng)求的,由于Android 4.0之前Tag存儲(chǔ)在靜態(tài)map里,如果Glide使用setTag(int key, final Object tag)方法標(biāo)記請(qǐng)求則可能會(huì)導(dǎo)致內(nèi)存泄露,所以Glide默認(rèn)使用view.setTag(tag)標(biāo)記請(qǐng)求,你就不能重復(fù)調(diào)用了。 解決辦法:如果你需要為ImageView設(shè)置Tag,必須使用setTag(int key, final Object tag)及getTag(int key)方法,其中key必須是合法的資源ID以確保key的唯一性,典型做法就是在資源文件中聲明type="id"的item資源。

2、placeholder()導(dǎo)致的圖片變形問(wèn)題 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?問(wèn)題描述:使用.placeholder()方法在某些情況下會(huì)導(dǎo)致圖片顯示的時(shí)候出現(xiàn)圖片變形的情況。這是因?yàn)镚lide默認(rèn)開(kāi)啟的crossFade動(dòng)畫(huà)導(dǎo)致的TransitionDrawable繪制異常,詳細(xì)描述和討論可以看一下這個(gè)#363 issue。根本原因就是你的placeholder圖片和你要加載顯示的圖片寬高比不一樣,而Android的TransitionDrawable無(wú)法很好地處理不同寬高比的過(guò)渡問(wèn)題,這的確是個(gè)Bug,是Android的也是Glide的。 解決辦法:使用.dontAnimate()方法禁用過(guò)渡動(dòng)畫(huà),或者使用animate()方法自己寫(xiě)動(dòng)畫(huà),再或者自己修復(fù)TransitionDrawable的問(wèn)題。

3、ImageView的資源回收問(wèn)題 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 問(wèn)題描述:默認(rèn)情況下,Glide會(huì)根據(jù)with()使用的Activity或Fragment的生命周期自動(dòng)調(diào)整資源請(qǐng)求以及資源回收。但是如果有很占內(nèi)存的Fragment或Activity不銷(xiāo)毀而僅僅是隱藏視圖,那么這些圖片資源就沒(méi)辦法及時(shí)回收,即使是GC的時(shí)候。 解決辦法:可以考慮使用WeakReference,如:? ? final WeakReferenceimageViewWeakReference = new WeakReference<>(imageView);

ImageView target = imageViewWeakReference.get();

if (target != null) {

Glide.with(context).load(uri).into(target);

}

4、ImageView的scaleType問(wèn)題

scaleType默認(rèn)為fitCenter模式,如果你想設(shè)置成centerInside,不好意思,3.x還沒(méi)有這個(gè)方法,參見(jiàn)這個(gè)#591 issue,折中的解決辦法就是放棄使用centerInside,或者結(jié)合android:scaleType="centerInside"和.dontTransform()使用以禁止Glide對(duì)資源進(jìn)行轉(zhuǎn)換。

如果你想要ImageView的寬高根據(jù)圖片資源的大小而定(即使用wrap_comtent),那么你就必須明確告訴Glide我想加載原始資源:使用android:scaleType="center",或者.dontTransform(),或者.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)。

不推薦使用fitXY,因?yàn)檫@樣Glide會(huì)加載全尺寸圖像到內(nèi)存中而造成不必要的內(nèi)存占用。

5、異步線(xiàn)程完成后加載圖片的崩潰問(wèn)題

問(wèn)題描述:通常情況下,異步線(xiàn)程會(huì)被約束在Activity生命周期內(nèi),所以異步線(xiàn)程完成后使用Glide加載圖片是沒(méi)有問(wèn)題的。但如果你的異步線(xiàn)程在Activity銷(xiāo)毀時(shí)沒(méi)有取消掉,那么異步線(xiàn)程完成后就Glide就無(wú)法為一個(gè)已銷(xiāo)毀的Activity加載圖片資源,拋出的異常如下(在with()方法中就進(jìn)行判斷并拋出異常):

java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity

at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)

at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)

at com.bumptech.glide.Glide.with(Glide.java:653)

at com.frank.glidedemo.TestActivity.onGetDataCompleted(TestActivity.java:23)

at com.frank.glidedemo.TestActivity.access$000(TestActivity.java:10)

at com.frank.glidedemo.TestActivity$BackgroundTask.onPostExecute(TestActivity.java:46)

at com.frank.glidedemo.TestActivity$BackgroundTask.onPostExecute(TestActivity.java:28)

at android.os.AsyncTask.finish(AsyncTask.java:632)

at android.os.AsyncTask.access$600(AsyncTask.java:177)

at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:157)

at android.app.ActivityThread.main(ActivityThread.java:5356)

at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:515)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)

at dalvik.system.NativeStart.main(Native Method)

}

解決辦法:正確管理Background Threads(異步線(xiàn)程),當(dāng)Activity停止或銷(xiāo)毀時(shí),停止所有相關(guān)的異步線(xiàn)程,停止所有后續(xù)的UI操作。或者加載前使用isFinishing()或isDestroyed()進(jìn)行限制(不建議這種處理方式)。

6、由于Bitmap復(fù)用導(dǎo)致的在某些設(shè)備上圖片錯(cuò)亂的問(wèn)題

問(wèn)題描述: Glide默認(rèn)使用BitmapPool的方式對(duì)應(yīng)用中用到的Bitmap進(jìn)行復(fù)用,以減少頻繁的內(nèi)存申請(qǐng)和內(nèi)存回收,而且默認(rèn)使用的Bitmap模式為RGB565以減少內(nèi)存開(kāi)銷(xiāo)。但在某些設(shè)備上(通常在Galaxy系列5.X設(shè)備上很容易復(fù)現(xiàn))某些情況下會(huì)出現(xiàn)圖片加載錯(cuò)亂的問(wèn)題,具體詳見(jiàn)這個(gè)#601 issue。原因初步確定是OpenGL紋理渲染異常。

解決辦法:GlideModule使用PREFER_ARGB_8888(Glide4.X已經(jīng)默認(rèn)使用該模式了),雖然內(nèi)存占用比RGB565更多一點(diǎn),但可以更好地處理有透明度Bitmap的復(fù)用問(wèn)題。或者禁用Bitmap復(fù)用setBitmapPool(new BitmapPoolAdapter())來(lái)修復(fù)這個(gè)問(wèn)題(不推薦這種處理方式)

6、Picasso和Glide的區(qū)別

1、Glide比Picasso加載速度快

2、默認(rèn)情況Glide更有利于減少OutOfMemoryError的發(fā)生,不過(guò)Picasso的圖片質(zhì)量更高

3、Glide支持gif,Picasso不支持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,285評(píng)論 25 708
  • 一、簡(jiǎn)介 在泰國(guó)舉行的谷歌開(kāi)發(fā)者論壇上,谷歌為我們介紹了一個(gè)名叫Glide的圖片加載庫(kù),作者是bumptech。這...
    天天大保建閱讀 7,579評(píng)論 2 28
  • 簡(jiǎn)歷從一開(kāi)始的基本框架,到動(dòng)手制作填寫(xiě),已經(jīng)斷斷續(xù)續(xù)準(zhǔn)備了一個(gè)多月,應(yīng)屆生的簡(jiǎn)歷內(nèi)容很少,在計(jì)劃之中,校園經(jīng)歷和實(shí)...
    王家人寧閱讀 790評(píng)論 0 0
  • 平常下班沒(méi)事做,畫(huà)畫(huà)畫(huà)著玩兒~作為一個(gè)門(mén)外漢,沒(méi)有專(zhuān)業(yè)基礎(chǔ),畫(huà)得也不專(zhuān)業(yè),全是晚上在床上用懶人桌畫(huà)的,買(mǎi)的飛樂(lè)鳥(niǎo)的...
    墨陌沫92閱讀 265評(píng)論 2 2
  • 今天,你26歲了 和我一樣大,大了幾個(gè)月 去年的九月回來(lái)泉州,開(kāi)啟了新的旅程,然后遇到一群好玩的人,遇到了你 在生...
    井姐吖閱讀 479評(píng)論 0 3