android Glide简单使用
今天,简单讲讲Android里Glide的简单使用。
Android框架系列:
二.android Glide简单使用
对于Glide这个加载图片的框架,很多人都在用,我之前使用的是ImageLoader,最近查资料时,发现Glide才是Google推荐的加载图片框架,功能非常强大,而且还有Google专人维护,要知道,ImageLoader已经没人维护了,除了问题可没人解答。所以有必要整理一下Glide的使用。
Glide是谷歌为我们推荐的一个图片加载库。为什么要选择使用Glide呢?
- 1、代码有人维护,不至于出现问题,项目组都搞不定的时候问题无法解决。(ImageLoader已没人维护了)
- 2、代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来有些生疏)
- 3、功能强大(400多k的包,包含很多功能,例如:像加载Gif图片就是Picasso做不到的)
下面我们就来介绍下Glide的用法:
Glide的基本使用
导入库
compile 'com.github.bumptech.glide:glide:3.7.0'
添加代码混淆(可加可不加)
- -keep public class * implements com.bumptech.glide.module.GlideModule
- -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
- **[] $VALUES;
- public *;
- }
- # for DexGuard only
- -keepresourcexmlelements manifest/application/meta-data@value=GlideModule
这个别忘了,不要粗心哦,很容易忘得,最简单的问题,往往需要最简单的搞定啦。
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.INTERNET" />
简单使用例子
- // For a simple view:
- @Override
- public void onCreate(Bundle savedInstanceState) {
- ...
- ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
- Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
- }
- // For a simple image list:
- @Override
- public View getView(int position, View recycled, ViewGroup container) {
- final ImageView myImageView;
- if (recycled == null) {
- myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
- } else {
- myImageView = (ImageView) recycled;
- }
- String url = myUrls.get(position);
- Glide
- .with(myFragment)
- .load(url)
- .centerCrop()
- .placeholder(R.drawable.loading_spinner)
- .crossFade()
- .into(myImageView);
- return myImageView;
- }
Glide使用详解
加载网络图片
Glide.with(context).load(internetUrl).into(targetImageView);
从文件加载图片
- File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
- Glide.with(context).load(file).into(imageViewFile);
从资源id加载图片
- int resourceId = R.mipmap.ic_launcher;
- Glide.with(context).load(resourceId).into(imageViewResource);
从uri加载图片
Glide.with(context).load(uri).into(imageViewUri);
播放本地mp4,只能是本地(获取MP4视频的缩略图)
- String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
- Glide.with( context ).load( Uri.fromFile( **new **File( filePath ) ) ).into( imageViewGifAsBitmap );
加载Gif图片
- String gifUrl = "xxxxx";
- Glide.with( context ).load( gifUrl ).into( imageViewGif );
用bitMap播放Gif.asBitmap()
Glide.with( context ).load( gifUrl ).asBitmap().into( imageViewGifAsBitmap );
强制转化为Gif.asGif()
Glide.with( context ).load( gifUrl ).asGif().error( R.drawable.full_cake ).into( imageViewGif );
设置默认占位图.placeholder()
设置加载失败的图片.error()
Glide.with( context ).load( gifUrl ).placeholder( R.drawable.cupcake ).error( R.drawable.full_cake ).into( imageViewGif );
.fallback()
除了上面两种‘异常情况’,还有一种情形就是打开手机的通讯录的时候,可以看到你给有些喜欢的人设置了照片,然而有些可怜的人并没给有,总不能在那里留下一片空白吧,这个时候相当于传递了Null,传递null时,这个callback方法就会被调用。
- Glide.with(context)
- .load( null)//加载空指针的时候
- .fallback( R.drawable.wuyanzu)
- .into( imageViewNoFade );
设置加载动画
其实这个是默认的,但是你还是可以写出来,渐显动画
1、.crossFade()
:Glide提供淡如淡出
Glide.with(context).load().placeholder(R.mipmap.ic_launcher) .error(R.mipmap.future_studio_launcher).crossFade().into(imageViewFade);
这里还有一个.fadeFade(int duration)
,设置动画时间。如果你不想要动画可以加上.dontAnimate()
2、.animate(android.R.anim.slide_in_left)
:Android系统提供,从左到右滑出加载动画
调整图片大小.resize(int ,int )
单位是像素,裁剪你的图片大小。其实Glide已经会自动根据你ImageView裁剪照片来放在缓存中了。但是不想适应ImageView大小的时候,可以调用这个方法.override()
为ImageView指定大小。
Glide.with(context).load(image).override(600, 200) .into(imageViewResize);
裁剪图片.fitCenter()
和.CenterCrop()
Glide清楚在合适的ImageView中加载合适的Image.当需要裁剪大小时,有个.centerCrop
方法,这个方法的裁剪会让你的ImageView周围不会留白,还有一个.fitCenter()
方法,表示让你的Image完全显示,尺寸不对时,周围会留白。
设置缩略图.thumbnail()
.thumbnail()
方法的目的就是让用户先看到一个低解析度的图,点开后,再加载一个高解析度的图。
- //表示为原图的十分之一
- Glide.with( context ).load(image).thumbnail( 0.1f ).into( imageView2 );
一种更高级的缩略图加载方式:
当缩略图也需要通过网络加载全部解析度的时候。
- private void loadImageThumbnailRequest() {
- DrawableRequestBuilder<String> thumbnailRequest = Glide.with( context ).load( eatFoodyImages[2] );
- Glide.with( context ).load( UsageExampleGifAndVideos.gifUrl ).thumbnail( thumbnailRequest ).into( imageView3 );
- }
设置图片显示效果(圆角、圆形、高斯模糊、蒙板、裁剪等等).bitmapTransform()
- Glide.with(this).load(R.mipmap.ic_image_sample)
- //模糊
- .bitmapTransform(new BlurTransformation(this))
- //圆角
- .bitmapTransform(new RoundedCornersTransformation(this, 24, 0, RoundedCornersTransformation.CornerType.ALL))
- //遮盖
- .bitmapTransform(new MaskTransformation(this, R.mipmap.ic_launcher))
- //灰度
- .bitmapTransform(new GrayscaleTransformation(this))
- //圆形
- .bitmapTransform(new CropCircleTransformation(this))
- .into(mResultIv);
除此之外还有实现诸如马赛克、明暗度等更多滤镜处理:
- ToonFilterTransformation
- SepiaFilterTransformation
- ContrastFilterTransformation
- InvertFilterTransformation
- PixelationFilterTransformation
- SketchFilterTransformation
- SwirlFilterTransformation
- BrightnessFilterTransformation
- KuwaharaFilterTransformation
- VignetteFilterTransformation
Glide的缓存
用过手机的都知道,当划上划下一个ListView的时候,第二次都比第一次快,就是因为为GlideView对资源进行了缓存,而且封装的很好,甚至不需要自己去设定缓存大小,Glide会智能地自己给我们根据设备设置缓存大小。
缓存是为了减少或者杜绝多的网络请求。为了避免缓存,Glide用了内存缓存和‘外存缓存机制’,并且 提供了相应的方法,完全封装,不需要处理细节。Glide会自动缓存到内存,除非调用.skipMemoryCache( true )
。尽管调用了这个,Glide还是会缓存到外存,还有一种情形,就是有一张图片,但是这张图变化非常快,这个时候可能并不想缓存到外存中,就使用.diskCacheStrategy( DiskCacheStrategy.NONE )
。如果你两种都不需要,可以两个方法组合着一起使用。
自定义外存缓存机制
Glide默认会缓存Image的很多个版本,比如原图,如果你的imageView大小的缓存。.diskCacheStrategy()
有以下几种缓存策略:
- DiskCacheStrategy.NONE 什么都不缓存
- DiskCacheStrategy.SOURCE 只缓存最高解析图的image
- DiskCacheStrategy.RESULT 缓存最后一次那个image,比如有可能你对image做了转化
- DiskCacheStrategy.ALL image的所有版本都会缓存
Glide.with( context ).load( image ).diskCacheStrategy( DiskCacheStrategy.SOURCE ).into( imageViewFile );
修改缓存大小、位置、加载图片质量
和指定HttpClent为OkHttp一样,只不过我们需要配置一些信息在applyOptions()函数里面
- public class GlideConfigModule implements GlideModule {
- @Override
- public void applyOptions(Context context, GlideBuilder builder) {
- // 指定位置在packageName/cache/glide_cache,大小为MAX_CACHE_DISK_SIZE的磁盘缓存
- builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));
- //指定内存缓存大小
- builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
- //全部的内存缓存用来作为图片缓存
- builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
- builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);//和Picasso配置一样
- }
- @Override
- public void registerComponents(Context context, Glide glide) {
- }
- }
- <meta-data android:name="com.example.imageloadpk.adapter.config.GlideConfigModule"
- android:value="GlideModule"/>
一般的图片加载框架设置了磁盘缓存和内存缓存就行了,但是Glide还设置了一个图片缓存。
图片缓存 <= 内存缓存
- builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", ConfigConstants.MAX_CACHE_DISK_SIZE));
- //指定内存缓存大小
- builder.setMemoryCache(new LruResourceCache(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
- //全部的内存缓存用来作为图片缓存
- builder.setBitmapPool(new LruBitmapPool(ConfigConstants.MAX_CACHE_MEMORY_SIZE));
这里Glide不仅可以缓存图片,还可以缓存其他文件譬如视频之类,也就是说可以把他作为我们的缓存工具来使用,当然缓存方式还是使用LRU。这样我们就不必再去重新集成LruCache和DiskLruCache,再去申请空间,配置。直接可以复用Glide的。
使用缓存也加载动画
但是,动画默认是在图片没有缓存的情况下才加载,想想也是合理的,如果图片已近下载到本地加载速度将会非常快,这个时候使用动画过渡反而碍事。要让从缓存中图片呈现也加载动画不能通过这种方式实现,可以用监听器来做。
- private RequestListener<String, GlideBitmapDrawable> mAnimationRequestListener = new RequestListener<String, GlideBitmapDrawable>() {
- @Override
- public boolean onException(Exception e, String model, Target<GlideBitmapDrawable> target, boolean isFirstResource) {
- return false;
- }
- @Override
- public boolean onResourceReady(GlideBitmapDrawable resource, String model, Target<GlideBitmapDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
- dissProgress();
- if (isFromMemoryCache) {
- //如果是从缓存加载,设置动画效果
- mIvShow.setAnimation(AnimationUtils.loadAnimation(mContext, R.anim.scale));
- }
- //返回true表示拦截不再传递,false表示事件会传递下去
- return false;
- }
- };
请求优先级.priority()
加载图片肯定也是有先后顺序,Glide提供了.priority()
这个方法,它接收以下几个参数:
- Priority.LOW
- Priority.NORMAL
- Priority.HIGH
- Priority.IMMEDIATE
但是Glide并不一定会按照你的顺序来,只是尽量按照你的顺序来。(比如给一张很大的图片最高的优先权,但是它并不一定比低优先级的图先加载出来,这个时候只有使用缩略图了)
- Glide.with(mContext).load(Url.IMAGE_URL_TROCHILIDAE)
- .priority(Priority.HIGH).into(mIvTonyRight);
利用callback在非标准情况下加载图片
上面所有的情况都是加载图片到ImageView中,但是并不是所有的情况都是这样。譬如加载的控件类型不是ImageView,是个自定义的布局。或者加载为Background的形式。
可以使用SimpleTarget类型,这里指定他的大小为500*100,加载为背景图片
- .into(new SimpleTarget<Drawable>(500, 100) {
- @Override
- public void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) {
- mBtnClear.setBackground(resource);
- }
同理下载图片原理是一样
- .into(new SimpleTarget<Bitmap>() {
- @Override
- public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
- //toSave
- Log.d(TAG, "onResourceReady: save successful");
- }
- });
Glide中的回调:Targets
从上面的介绍,已经可以看出Glide内部封装了所有的细节,什么网络请求,什么缓存机制,当所有都就绪过后,自动切换回UI线程,更新ImageView。Targets就是Glide中的回调,当异步线程中所有的工作做完过后返回结果。说白了就是,当请求图片完成后,需要回调的方法。
SimpleTarget
- private SimpleTarget target = new SimpleTarget<Bitmap>() {
- @Override
- public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
- // do something with the bitmap
- // for demonstration purposes, let's just set it to an ImageView
- imageView1.setImageBitmap( bitmap );
- }
- };
- private void loadImageSimpleTarget() {
- Glide.with( context ) *// could be an issue!*
- .load( eatFoodyImages[0] )
- .asBitmap()//强制Glide返回一个Bitmap
- .into( target );
- }
注意事项:
1、上面这段代码不要写成匿名内部类的机制,原因就是java的自动垃圾回收机制可能在图片还没有加载好的时候就已经把你的Target回收了。
2、注意.with()里面的参数,Glide的请求是和传进去的Context共存亡的,如果传一个Activity进去,当Activity GC过后,你的请求也就GC了,但是如果这样传:.with(context.getApplicationContext() )
.当你的Activity GC过后,请求还是会继续,回调还是会继续。
有size的Target
如果传给into()
.的是一个ImageView,但是图片的size比ImageView的Size打,Glide为了节省时间,会加载小的那个size的Image。但是这对Target并不适用,以为这里并不知道SIze。但是如果知道image应该多大,可以传递给Target.就像下面这样:
- private SimpleTarget target2 = new SimpleTarget<Bitmap>( 250, 250 ) {
- @Override
- public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
- imageView2.setImageBitmap( bitmap );
- }
- };
- private void loadImageSimpleTargetApplicationContext() {
- Glide.with(context.getApplicationContext()); *// safer!*
- .load( eatFoodyImages[1] )
- .asBitmap()
- .into( target2 );
- }
ViewTarget
适用于想Glide加载到自定义View中去,
- public class FutureStudioView extends FrameLayout {
- ImageView iv;
- TextView tv;
- public void nitialize(Context context) {
- inflate( context, R.layout.custom_view_futurestudio, this );
- iv = (ImageView) findViewById( R.id.custom_view_image );
- tv = (TextView) findViewById( R.id.custom_view_text );
- }
- public FutureStudioView(Context context, AttributeSet attrs) {
- super( context, attrs );
- initialize( context );
- }
- public FutureStudioView(Context context,AttributeSet attrs,int defStyleAttr) {
- super( context, attrs, defStyleAttr );
- initialize( context );
- }
- public void setImage(Drawable drawable) {
- iv = (ImageView) findViewById( R.id.custom_view_image );
- iv.setImageDrawable( drawable );
- }
- }
还有notificationTarget 和AppWidget作为扩展自行研究喽。
监听器配置.listener()
- Glide.with(getContext()).load(url)
- .listener(mRequestListener)//配置监听器
- .placeholder(Drawables.sPlaceholderDrawable)
- .error(Drawables.sErrorDrawable)
- .into(mImageView);
- private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
- @Override
- public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
- //显示错误信息
- Log.w(TAG, "onException: ", e);
- //打印请求URL
- Log.d(TAG, "onException: " + model);
- //打印请求是否还在进行
- Log.d(TAG, "onException: " + target.getRequest().isRunning());
- return false;
- }
- @Override
- public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
- return false;
- }
- };
这里的onException捕获异常,如果返回true表示我们自己处理掉了异常,false表示交给Glide去处理,因为我们定义了.error()那么就显示error里面的内容。
这里onResourceReady表示是否准备资源显示,返回true表示用户自己已经设置好资源,包括截取操作,动画操作之类的,准备好显示。false表示交给Glide
如此修改后,就能够看到图片加载日志了,方便我们调试
替换掉自带的HttpClient
只需两步
Step1:
导入需要替换的HttpClient,可以选择Volley也可以选择OkHttp,我们使用Okhttp,在Module的build.gradle文件中配置
- dependencies {
- compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'
- compile 'com.squareup.okhttp3:okhttp:3.3.1'
- or
- compile 'com.github.bumptech.glide:volley-integration:1.4.0@aar'
- compile 'com.mcxiaoke.volley:library:1.0.8'
- }
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
这个版本具体选择多少,可以在https://github.com/bumptech/glide/wiki/Integration-Libraries这里查询到
Step2:
在AndroidMainfest.xml文件中写入
- <meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule"
- android:value="GlideModule"/>
你可能会有和我一样的疑问,Glide可以通过在配置清单里面配置
能不能写几个meta-data标签,一个标签里面配置一点参数
经过测试,发现这样做也是可以的。但是如果是同一种配置信息,比如你集成了OkHttp,又写一个标签集成Volley,最后一个会把前面的覆盖掉。
注意事项
1、前面我们已经学习到asGif()可以加载gif图,asBitmap()可以加载静态gif图即gif图的第一帧,如果非gif图用asGif()方法加载呢?这时候会报错。。Glide默认可以自动识别图片格式,加载gif图,所以在不确定图片格式的情况下,不要直接写asGif哦。
2、You cannot start a load for a destroyed activity这样的异常如何处理?
记住不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext。希望可以帮你避免这个问题。
3、为什么有的图片第一次加载的时候只显示占位图,第二次才显示正常的图片呢?
.如果你刚好使用了这个圆形Imageview库或者其他的一些自定义的圆形Imageview,而你又刚好设置了占位的话,那么,你就会遇到第一个问题。如何解决呢?
方案一: 不设置占位;
方案二:使用Glide的Transformation API自定义圆形Bitmap的转换。这里是一个已有的例子;
方案三:使用下面的代码加载图片:
- Glide.with(mContext)
- .load(url)
- .placeholder(R.drawable.loading_spinner)
- .into(new SimpleTarget<Bitmap>(width, height) {
- @Override
- public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
- // setImageBitmap(bitmap) on CircleImageView
- }
- };
4、图片大小拉伸问题
有时候你会发现网络加载完了之后会有拉伸现象,而你的控件大小明明是自适应的呀,这是为什么呢,请你检查下你是否设置了占位图,有的话请去掉就ok了。
简单总结一下,我这里讲了Glide比较全面的用法,有如何加载图片,Glide的缓冲设置,Glide设置圆角,Glide设置图片的background,Glide加载GIF图片等,大家使用的话一般了解加载图片和圆角图片就可以了。这里在列举一下。
- //圆形裁剪
- 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);
android Glide简单使用就讲完了。
就这么简单。
android Glide简单使用的更多相关文章
- Android图片加载与缓存开源框架:Android Glide
<Android图片加载与缓存开源框架:Android Glide> Android Glide是一个开源的图片加载和缓存处理的第三方框架.和Android的Picasso库类似,个人感觉 ...
- Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果
Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...
- android glide图片加载框架
项目地址: https://github.com/bumptech/glide Glide作为安卓开发常用的图片加载库,有许多实用而且强大的功能,那么,今天就来总结一番,这次把比较常见的都写出来,但并 ...
- 比较强大 优秀的开源框架 :Android图片加载与缓存:Android Glide 的用法
使用Android Glide,需要先下载Android Glide的库,Android Glide在github上的项目主页: https://github.com/bumptech/glide . ...
- 037 Android Glide图片加载开源框架使用
1.Glide简单介绍 Glide是一款由Bump Technologies开发的图片加载框架,使得我们可以在Android平台上以极度简单的方式加载和展示图片.Glide是一个快速高效的Androi ...
- Android 实现简单音乐播放器(二)
在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我简单总结一些功能实现过程中的要点和有趣的细节,结合MainActivity.java代码进行说明(写出 ...
- Android 实现简单音乐播放器(一)
今天掐指一算,学习Android长达近两个月了,今天开始,对过去一段时间的学习收获以及遇到的疑难杂症做一些总结. 简单音乐播放器是我自己完成的第一个功能较为完整的APP,可以说是我的Android学习 ...
- Android课程---Android Studio简单设置
Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以选择使用炫酷的黑色界面.Settings-->Appearance-->Theme, ...
- Android Glide数据更新及内存缓存、硬盘缓存清理
[转] 原文 Android Glide数据更新及内存缓存.硬盘缓存清理 Android的Glide在加载图片时候内部默 ...
随机推荐
- JAVA首次课堂测试总结
暑期生活已经结束,新的学期也已经开始,而暑期放假之前约定的JAVA首次课堂测试也如期的到来,本次测试真的可以学到和多东西,也有很多感想. 首先体会最深的就是系主任所说的软件工程不是那么好学的,真的需要 ...
- asp.net core选项Options模块的笔记
这篇博客是写给自己看的.已经不止一次看到AddOptions的出现,不管是在.net core源码还是别人的框架里面,都充斥着AddOptions.于是自己大概研究了下,没有深入,因为,我的功力还是不 ...
- PAT (Advanced Level) Practise 1002 解题报告
GitHub markdownPDF 问题描述 解题思路 代码 提交记录 问题描述 A+B for Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 ...
- XamarinAndroid组件教程设置自定义子元素动画(一)
XamarinAndroid组件教程设置自定义子元素动画(一) 如果在RecyclerViewAnimators.Animators中没有所需要的动画效果,就可以自定义一个.此时,需要让自定义的动画继 ...
- BZOJ.4513.[SDOI2016]储能表(数位DP)
BZOJ 洛谷 切了一道简单的数位DP,终于有些没白做题的感觉了...(然而mjt更强没做过这类的题也切了orz) 看部分分,如果\(k=0\),就是求\(\sum_{i=0}^n\sum_{j=0} ...
- BZOJ.3532.[SDOI2014]LIS(最小割ISAP 退流)
BZOJ 洛谷 \(LIS\)..经典模型? 令\(f_i\)表示以\(i\)结尾的\(LIS\)长度. 如果\(f_i=1\),连边\((S,i,INF)\):如果\(f_i=\max\limits ...
- 树形动态规划(树状DP)小结
树状动态规划定义 之所以这样命名树规,是因为树形DP的这一特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系.利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的记忆化搜索的 ...
- FPGA - 认识FPGA
一.何为FPGA? FPGA,英文全拼:Field-Programmable Gate Array 现场可编程门阵列,它是在PAL.GAL.CPLD等可编程器件的基础上进一步发展的产物.它是作为专用集 ...
- Nginx (LNMP+https)
单向认证与双向认证的概念 什么是单向认证 单项认证就是比如你有个密码用户名然后和服务器上的用户信息进行比对一致的话你们就可以建立连接. 什么是双向认证 SSL的双向认证就是客户端要获取服务端的证书,检 ...
- Mssql数据库与Excel导数据
*.xls 2003的excel有行数限制,65535行好像,所以数据库行数多的时候,选择导出为*.xlsx文件 要装一下Microsoft.ACE.OLEDB.12.0(以下简称 ACE 引擎) ...