怎么写篇看着舒服的日志

mikel阅读(952)

 做自媒体不是容易事儿,文字功底不能差之外,排版和配图依然很重要,用户看得赏心悦目,主要是让人看着舒服很重要。

个人总结几点:

1.排版:
不要用乱七八糟的背景,如果非得用,建议用淡颜色的背景;
字体建议:微软雅黑  字号:3(18px);
每个段落加空行,隔开,这样不至于密密麻麻的都是字儿,别人看了头大;
标点符号一定要有。

2.配图:
配图一定要贴合日志主题,否则就不要配图,
如果配图有水印的,一定要用工具去掉,那样才显得专业,去水印的工具,推荐“快速去除图片水印-inpaint”

3. 校稿:
别错别字满篇,看你日志是学习来了,不是给你矫正错别字的,尽管你的语文是体育老师教的,也不能这么显摆儿!
写完之前先自己读一遍。

4.手机发稿前,先设成私密,然后电脑上排版再发吧!否则,排版和字体都会让人看着舒服的。

[转载]帝国CMS整合Discuz通行证接口教程 帝国cms - 安全、强大、稳定、灵活

mikel阅读(1017)

[转载]帝国CMS整合Discuz通行证接口教程 帝国cms – 安全、强大、稳定、灵活.
帝国CMS整合Discuz有两种方式:
方式一、用Ucenter接口整合。使用Ucenter接口整合无需安装通行证跟万能会员接口。
方式二、用Discuz通行证接口整合。需先安装万能会员接口,然后再安装通行证。

Ucenter接口及Discuz通行证下载地址:http://www.phome.net/OpenSource/

先前给大家讲解了Ucenter接口整合教程(点击查看),今天我为大家讲解用Discuz通行证接口整合的步骤:
第 1 步:安装帝国CMS万能会员接口
(1)、将万能会员接口包里的“update”目录上传至帝国CMS的“e”目录里(包含update目录本身)。

复制到帝国CMS的“e”目录里:

(2)、执行/e/update/index.php文件,进入接口设置界面设置参数:

接口范例:选择Discuz论坛
操作动作:选择安装接口
用户表:Discuz数据库.表前缀members,如“database.cdb_members”
会员注册地址:填Discuz的注册地址,如:http://localhost/discuz/register.php
会员登陆地址:填Discuz的登陆地址,如:http://localhost/discuz/logging.php?action=login
会员退出地址:填Discuz的退出地址,如:http://localhost/discuz/logging.php?action=logout

Discuz-X的地址为以下:
会员注册地址填:http://localhost/discuz/member.php?mod=register
会员登陆地址填:http://localhost/discuz/member.php?mod=logging&action=login
会员退出地址填:http://localhost/discuz/member.php?mod=logging&action=logout

设置后点提交将会提示整合万能会员接口完毕。

(3)、删除e/update目录里的文件。防止被恶意设置。

第 2 步:上传通行证接口包里的文件至Discuz论坛目录
将通行证接口包里的“logging.php”、“LoginDiscuz.php”、“register.php”三个文件上传到Discuz目录:

复制到Discuz论坛目录里:

第 3 步:修改通行证配置文件:LoginDiscuz.php
修改Discuz论坛目录下的LoginDiscuz.php文件配置:

帝国CMS安装目录参数:(相对于Discuz安装目录,后面需加/)
$EcmsInstallPath:设置帝国CMS安装目录。
举例:

例1:
帝国CMS安装目录:D:/web/ecms
Discuz安装目录:D:/web/discuz
因为帝国CMS安装在discuz的上一级目录的ecms目录里。所以$EcmsInstallPath=”../ecms/”;

例2:
帝国CMS安装目录:D:/web/
Discuz安装目录:D:/web/discuz
因为帝国CMS安装在discuz的上一级目录里。所以$EcmsInstallPath=”../”;

例3:
帝国CMS安装目录:D:/web/discuz/ecms
Discuz安装目录:D:/web/discuz
因为帝国CMS安装在discuz的子目录ecms目录里。所以$EcmsInstallPath=”ecms/”;

COOKIE设置参数(Discuz跟帝国CMS不在一个域名下需要修改,否则不用修改设置)
$EcmsCookieDomain:cookie作用域
$EcmsCookiePath:cookie作用路径
举例:

如果:
帝国CMS安装域名为:http://www.xxx.com
Discuz论坛域名为:http://bbs.xxx.com
因为域名不同,那么就需要修改COOKIE设置,需要按下面设置:
$EcmsCookieDomain=”.xxx.com”;
$EcmsCookiePath=”/”;

注册会员时帐号COOKIE保存时间参数(不需要修改,默认即可)
$EcmsRegLogintime

第 4 步:至此,Discuz通行证接口整合完毕。

第 5 步:修改帝国CMS的登陆表单为Discuz的登陆表单。
登陆帝国CMS后台 > “模板管理” > “公共模板” > “修改JS调用登陆模板”:将模板修改为如下:

<form name=”login” method=”post” action=”discuz论坛地址/logging.php?action=login&amp;loginsubmit=yes”>
<input type=”hidden” name=”referer” value=”登陆返回地址“>
<input type=”hidden” name=”action” value=”login” />
<input type=”hidden” name=”loginfield” value=”username”>
用户名:<input name=”username” type=”text” class=”inputText” size=”16″ />&nbsp;
密码:<input name=”password” type=”password” class=”inputText” size=”16″ />&nbsp;
<input type=”submit” name=”loginsubmit” value=”登陆” class=”inputSub”>&nbsp;
<input type=”button” name=”Submit2″ value=”注册” class=”inputSub” onclick=”window.open(‘[!–news.url–]e/member/register’);” />
</form>
[!–empirenews.template–]
&raquo;&nbsp;<font color=red><b>[!–username–]</b></font>&nbsp;&nbsp;<a href=”[!–news.url–]e/member/my” target=”_parent”>[!–groupname–]</a>&nbsp;[!–havemsg–]&nbsp;<a href=”[!–news.url–]e/space/?userid=[!–userid–]” target=_blank>我的空间</a>&nbsp;&nbsp;<a href=”[!–news.url–]e/member/msg” target=_blank>短信息</a>&nbsp;&nbsp;<a href=”[!–news.url–]e/member/fava” target=_blank>收藏夹</a>&nbsp;&nbsp;<a href=”[!–news.url–]e/member/cp” target=”_parent”>控制面板</a>&nbsp;&nbsp;<a href=”[!–news.url–]e/enews?enews=exit&ecmsfrom=9″ onclick=”return confirm(‘确认要退出?’);”>退出</a>

说明:(红色部分需要修改)
discuz论坛地址:设置为你的Discuz论坛访问地址,如:”http://www.xxx.com/bbs/”。
登陆返回地址:必须是.php扩展名文件,如果不是.php扩展名可以在后面加?.php,如:”http://www.xxx.com/index.html?.php”

其他说明
(1)、通行证整合后“帝国CMS的登录与退出”要全转向“Discuz的登录与退出”页面,不再使用原帝国CMS的登录与退出地址。
(2)、如果在A机器登录Discuz后,并保存COOKIE,然后到B机器重新登录,系统只认B机器的数据,也就是说,系统登录只认最后一次登录的机器。
(3)、帝国CMS后台管理会员没有显示会员组说明此会员未登录帝国系统或论坛,登录的会员自动转为帝国默认会员组。
(4)、如果要整合Discuz积分可以设置万能会员接口将点数字段改为Discuz的积分字段名即可。

[转载]从代码分析Android-Universal-Image-Loader的图片加载、显示流程 - 小吉吉 - 博客园

mikel阅读(832)

[转载]从代码分析Android-Universal-Image-Loader的图片加载、显示流程 – 小吉吉 – 博客园.

UNIVERSAL IMAGE LOADER. PART 3(四个DisplayImage重载方法详解)中, 我们学习了Android-Universal-Image-Loader(以下简称UIL)中四个DisplayImage重载方法的使用,如果你还没 有学习,最好先返回去看看,不然可能不理解这篇文章。在这篇文章中我们将主要探讨Android-Universal-Image-Loader的主要流 程和这些流程相关的类的分析。

我们先了解一下UIL加载图片的流程(可以通过查看ImageLoader.displayImage(…)方法分析得出),如下图

image

从上图中,我们可以看出,UIL加载图片的 一般流程是先判断内存中是否有对应的Bitmap,再判断磁盘(disk)中是否有,如果没有就从网络中加载。最后根据原先在UIL中的配置判断是否需要 缓存Bitmap到内存或磁盘中。Bitmap加载完后,就对它进行解析,然后显示到特定的ImageView中。

有了对UIL对图片加载和处理流程的初步认识之后,我们就可以着手分析它的源代码了。先从ImageLoader.displayImage(…)入手,毕竟一切都因它而始。

public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options,
ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {
//检查UIL的配置是否被初始化
checkConfiguration();
if (imageAware == null) {
throw new IllegalArgumentException(ERROR_WRONG_ARGUMENTS);
}
if (listener == null) {
listener = emptyListener;
}
if (options == null) {
options = configuration.defaultDisplayImageOptions;
}

if (TextUtils.isEmpty(uri)) {
engine.cancelDisplayTaskFor(imageAware);
listener.onLoadingStarted(uri, imageAware.getWrappedView());
if (options.shouldShowImageForEmptyUri()) {
imageAware.setImageDrawable(options.getImageForEmptyUri(configuration.resources));
} else {
imageAware.setImageDrawable(null);
}
listener.onLoadingComplete(uri, imageAware.getWrappedView(), null);
return;
}
//计算Bitmap的大小,以便后面解析图片时用
ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageAware, configuration.getMaxImageSize());
String memoryCacheKey = MemoryCacheUtils.generateKey(uri, targetSize);
engine.prepareDisplayTaskFor(imageAware, memoryCacheKey);

listener.onLoadingStarted(uri, imageAware.getWrappedView());
//Bitmap是否缓存在内存?
Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);
if (bmp != null &amp;&amp; !bmp.isRecycled()) {
L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);

if (options.shouldPostProcess()) {
ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
options, listener, progressListener, engine.getLockForUri(uri));
//处理并显示图片
ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo,
defineHandler(options));
if (options.isSyncLoading()) {
displayTask.run();
} else {
engine.submit(displayTask);
}
} else {
//显示图片
options.getDisplayer().display(bmp, imageAware, LoadedFrom.MEMORY_CACHE);
listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp);
}
} else {
if (options.shouldShowImageOnLoading()) {
imageAware.setImageDrawable(options.getImageOnLoading(configuration.resources));
} else if (options.isResetViewBeforeLoading()) {
imageAware.setImageDrawable(null);
}

ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
options, listener, progressListener, engine.getLockForUri(uri));
//启动一个线程,加载并显示图片
LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo,
defineHandler(options));
if (options.isSyncLoading()) {
displayTask.run();
} else {
engine.submit(displayTask);
}
}
}

代码有点多,但是有很多代码是进行异常判断处理和函数的回调,为了先把握整体的流程,我们先放弃细节方面的追踪。基本上重要的处理流程我都有用注释标出。 不过,从这段代码中我们也可以看出这段代码的结构非常清晰。对图片的整个的加载流程都有对应的监听接口 (ImageLoadingListener.onLoadingStarted,ImageLoadingListener.onLoadingComplete,ImageLoadingListener 这个类就是用来监听图片的加载过程的),也就是说整个的图片加载过程程序员都可以进行相应的处理。我们先关注一下图片从无到有的加载过程,毕竟这部分是大 家最为关心的。看到第63行中的LoadAndDisplayImageTask,跟进LoadAndDisplayImageTask.run()方法 中。在这个run()方法中,除了 bmp = tryLoadBitmap();这一句是对图片进行加载,其他的函数都是对Bitmap进行处理或者显示。我们继续进入看看。

private Bitmap tryLoadBitmap() throws TaskCancelledException {
Bitmap bitmap = null;
try {
//尝试从磁盘缓存中读取Bitmap
File imageFile = configuration.diskCache.get(uri);
if (imageFile != null &amp;&amp; imageFile.exists()) {
L.d(LOG_LOAD_IMAGE_FROM_DISK_CACHE, memoryCacheKey);
loadedFrom = LoadedFrom.DISC_CACHE;

checkTaskNotActual();
bitmap = decodeImage(Scheme.FILE.wrap(imageFile.getAbsolutePath()));
}
//没有缓存在磁盘,从网络中下载图片
if (bitmap == null || bitmap.getWidth() &lt;= 0 || bitmap.getHeight() &lt;= 0) {
L.d(LOG_LOAD_IMAGE_FROM_NETWORK, memoryCacheKey);
loadedFrom = LoadedFrom.NETWORK;

String imageUriForDecoding = uri;
if (options.isCacheOnDisk() &amp;&amp; tryCacheImageOnDisk()) {
imageFile = configuration.diskCache.get(uri);
if (imageFile != null) {
imageUriForDecoding = Scheme.FILE.wrap(imageFile.getAbsolutePath());
}
}

checkTaskNotActual();
bitmap = decodeImage(imageUriForDecoding);

if (bitmap == null || bitmap.getWidth() &lt;= 0 || bitmap.getHeight() &lt;= 0) {
fireFailEvent(FailType.DECODING_ERROR, null);
}
}
} catch (IllegalStateException e) {
fireFailEvent(FailType.NETWORK_DENIED, null);
} catch (TaskCancelledException e) {
throw e;
} catch (IOException e) {
L.e(e);
fireFailEvent(FailType.IO_ERROR, e);
} catch (OutOfMemoryError e) {
L.e(e);
fireFailEvent(FailType.OUT_OF_MEMORY, e);
} catch (Throwable e) {
L.e(e);
fireFailEvent(FailType.UNKNOWN, e);
}
return bitmap;
}

从3~12行是尝试从磁盘缓存中加载Bitmap。第19行判断磁盘中是否有缓存,就开始进行网络下载(tryCacheImageOnDisk())。在tryCacheImageOnDisk()函数中有个tryCacheImageOnDisk()的 loaded = downloadImage()这行进行图片下载。

private boolean downloadImage() throws IOException {
InputStream is = getDownloader().getStream(uri, options.getExtraForDownloader());
return configuration.diskCache.save(uri, is, this);
}

这个函数做的事情很简单,就是获取一个实现Image Downloader的downloader(当然这里,作者根据网络情况将downloader分为慢速(slowNetworkDownloader)、正常速度(downloader)、网络拒绝(networkDeniedDownloader)情况下的download,在这里我们不展开,你只要知道他们是imageDownloader接口的实现者就行,后面的文章会探讨这个问题),然后利用Disk Cache将Bitmap写入磁盘缓存中。返回到之前我们进入downloadImage()函数中的tryLoadBitmap(),在将图片缓存到磁盘中。是否缓存到磁盘跟配置有关)后,紧接着调用 bitmap = decodeImage(Scheme.FILE.wrap(imageFile.getAbsolutePath()));解析图片。进入decodeImage()函数中,我们发现UIL调用Image Decoder进行图片的解析。

1 private Bitmap decodeImage(String imageUri) throws IOException {
2 ViewScaleType viewScaleType = imageAware.getScaleType();
3 ImageDecodingInfo decodingInfo = new ImageDecodingInfo(memoryCacheKey, imageUri, uri, targetSize, viewScaleType,
4 getDownloader(), options);
5 return decoder.decode(decodingInfo);
6 }

decode()函数最终是调用BaseImageDecoder.decode()方法进行解析的,这个利用之前获得的inputStream,直接从它身上读取数据,然后进行解析,并对整个下载任务的网络接口进行重置。

public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
Bitmap decodedBitmap;
ImageFileInfo imageInfo;

InputStream imageStream = getImageStream(decodingInfo);
try {
imageInfo = defineImageSizeAndRotation(imageStream, decodingInfo);
imageStream = resetStream(imageStream, decodingInfo);
Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);
decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);
} finally {
IoUtils.closeSilently(imageStream);
}

if (decodedBitmap == null) {
L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());
} else {
decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, decodingInfo, imageInfo.exif.rotation,
imageInfo.exif.flipHorizontal);
}
return decodedBitmap;
}

接下来,有了解析好的Bitmap对象后,剩下的就是在Image View对象中显示它了。我们回到文章一开始介绍到的ImageLoader.displayImage(…)函数中(相关的代码在文章的开头处可以看到)。

为了方便,我还是将ImageLoader.displayImage(…)中涉及的代码贴在下面。

1 DisplayBitmapTask displayBitmapTask = new DisplayBitmapTask(bmp, imageLoadingInfo, engine, loadedFrom);
2 runTask(displayBitmapTask, syncLoading, handler, engine);

我们进去DisplayBitmapTask.run()函数中看看。除去前面几行的ImageLoadingListener.ImageLoadingListener()代码,相关代码其实就一行 displayer.display(bitmap, imageAware, loadedFrom), 它其实就是调用BitmapDisplayer这个对象将Bitmap对象显示到ImageView上。根据实现BitmapDisplayer接口的不 同对象,还有SimpleBitmapDisplayer、FadeInBitmapDisplayer、 RoundedBitmapDisplayer、RoundedVignetteBitmapDisplayer这5种对象。

 

最后,让我们用任务流图概况以上的处理流程中对应接口。

在接下去的文章中,我们会介绍UIL中的包设计、缓冲、下载、多任务机制。

来自那年今日的提问

mikel阅读(973)

QQ空间的那年今天的追忆功能很有意思,2012年的8月10日,我写下舍 得两字以警示自已深悟其中之道,
惭愧时隔两年依然无法参悟其中之大智慧。

psbCAG0RQUE

 

很多道理看似潜显,不去实践很难悟出其中深意,不吃葡萄永远不知道葡萄是酸的

既然那年今日定了这个命题,那么今天就写下对“舍” “得”两字的几点感悟吧

先分开来说

1.“舍”要“舍”的智慧:互联网上能“舍”的人不多,为什么这么说,因为大家都想“得”到东西,不肯分享什么,更多的时候都在自己闭门造车式的重复造轮子,大家都在自作聪明的沉迷在自己的世界,浮躁的如热锅上的蚂蚁,看什么都想要,看什么都怀疑,看什么都否定,好不容易有人站出来“舍”得分享自己的干货,然后一帮人嗤之以鼻的说干得不够,其实很多事不需要掰开了揉碎了,事无巨细的一步步告诉你如何做,智者领会精神,愚者模仿方法,做看客永远只是个看客。

2.“得”要取之有道: 互联网这个提款机就在那里,里面的钱不多也不少,你想“得”就要悟自己的道,就像个巨大的提款机有万千取款密码,用密码打开可以从中获取你想要的资源和财富,你要想得到那就只有凭自己的能力获得那把打开提款机的密码,很多人得不到抱怨不可能,有些人勤奋的寻找,站着的永远不会腰疼,腰疼的总会得到回报。

合起来讲“舍”“得”就是个循环,懂得“舍”的人越是懂得分享的重要,于是“舍”得分享自己的经验教训出来,有人看到了会从中感悟到很多有益自己的东西,会去和分享者谈论彼此的心得体会,分享者又从谈论中悟到了东西,然后继续分享出来,如此循环往复,“舍”的越多,“得”的越多,这才是大智慧。

只得不舍,就是浪费,有舍必有得,得多得少在人

来自那年今日给自己出的题目,今日做个回答,写得有点儿乱,一点儿感悟,见笑了。

是谁偷了我的时间?!

mikel阅读(980)

 这么多媒体传播工具QQ、QQ空间、微信、微博、博客、手机客户端等等,无时无刻不再试图瓜分你的时间,是不是你有时候感觉一上午没做啥就没了?!时间利用率相当低,就是因为太容易被打断了并诱惑走了,QQ头像一闪,你就点开看看;手机提醒一响,你点开微信看看谁又发布朋友圈了,订阅的公众号又更新了,结果看完后,20几分钟没了; 当发现已经被偷了时间,结果自己还死不悔改的,看看谁发布了QQ空间日志,点个赞啊,谁又点评的有意思,去他空间看看吧,结果又20分钟没了;

不知道你们怎么被偷的,反正我的时间都是这么被这些杂七杂八的玩意儿偷走了!

于是决定屏蔽消息,3分钟立刻离开,超3分钟的内容,收藏,有闲散时间了,比如下班途中,晚上睡前再看,反正信息它就在那,不会跑也不会丢,又不着急,何必耽误阳光时间呢!

推荐一个好的时间管理工具:

www.doit.im 

[转载]ASP.NET MVC 插件式开发 - yangwen1 - 博客园

mikel阅读(1350)

[转载]MVC 插件式开发 – yangwen1 – 博客园.

在开发一个OA系统是,我们可能遇到 A模块. B模块 .C模块,这也模块组成一个完整的系统,买给客服。
现在又有一个客服要我们做一个OA系统,唉我们发现,跟上一个OA系统差不多,但没有C模块。怎么办?

修改源码,系统简单还好,但是一系统复杂到一定程度,修改源码改这改这就像重写了!

怎么办,MVC插件式开发帮你解决问题,先看演示,再看代码。

CCAV.WebSite 是主站,引用 CCAV.Modules.Category
CCAV.Modules.Category 就像当于一个模块,具体看演示。

 


通过主站可以访问到CCAV.Modules.Category 的控制器,如果 主站移除 对 CCAV.Modules.Category引用 将访问不到  CCAV.Modules.Category 你的控制器。
这样刚才的问题就解决了!

现在看一下主要代码。

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
VirtualPathConfig.Register();

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngineExpand());

AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}

VirtualPathConfig.Register();/ 注册虚拟路径提供者以实现模块化拆分

ViewEngines.Engines.Clear(); 移除全部视图引擎…..

ViewEngines.Engines.Add(new RazorViewEngineExpand()); 注册自己的视图引擎

///
/// 虚拟路径提供者配置
///

public class VirtualPathConfig
{
///
/// 注册虚拟路径提供者以实现模块化拆分
///

public static void Register()
{
GriffinVirtualPathProvider.Current.Add(new StaticFileProvider(new PluginFileLocator()));
GriffinVirtualPathProvider.Current.Add(new ViewFileProvider(new PluginFileLocator(), new ExternalViewFixer()));

HostingEnvironment.RegisterVirtualPathProvider(GriffinVirtualPathProvider.Current);
}
}

HostingEnvironment.RegisterVirtualPathProvider(GriffinVirtualPathProvider.Current);注册新的虚拟路径提供者:

StaticFileProvider 提供对图片、脚本、样式表等静态文件的访问

ViewFileProvider 视图文件提供

StaticFileProvider ViewFileProvider 继承于 IViewFileProvider 看他们的内部实现

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
using System.Web.Hosting;

namespace ItCast.Foundation.Hosting
{
///
/// 自定义的虚拟路径提供者。
///

public class GriffinVirtualPathProvider : VirtualPathProvider
{
private static readonly GriffinVirtualPathProvider Instance = new GriffinVirtualPathProvider();
private readonly List fileProviders = new List();

///
/// 初始化 GriffinVirtualPathProvider 类的新实例。
///

private GriffinVirtualPathProvider()
{
}

///
/// 获得实例。
///

public static GriffinVirtualPathProvider Current
{
get
{
return Instance;
}
}

///
/// 添加一个新的文件提供者。
///

///文件提供者。 public void Add(IViewFileProvider fileProvider)
{
if (fileProvider == null)
{
throw new ArgumentNullException("fileProvider");
}

this.fileProviders.Add(fileProvider);
}

///
/// 获取一个值,该值指示文件是否存在于虚拟文件系统中。
///

///
/// 如果该文件存在于虚拟文件系统中,则为 true;否则为 false。
///
///虚拟文件的路径。 public override bool FileExists(string virtualPath)
{
foreach (var provider in this.fileProviders)
{
if (provider.FileExists(virtualPath))
{
return true;
}
}

return base.FileExists(virtualPath);
}

///
/// 基于指定的虚拟路径创建一个缓存依赖项。
///

///主虚拟资源的路径。 ///一个路径数组,路径指向主要虚拟资源需要的其他资源。 ///虚拟资源被读取的 UTC 时间。 ///
/// 指定虚拟资源的 对象。
///
public override CacheDependency GetCacheDependency(
string virtualPath,
IEnumerable virtualPathDependencies,
DateTime utcStart)
{
foreach (var provider in this.fileProviders)
{
var result = provider.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
if (result is NoCache)
{
return null;
}

if (result != null)
{
return result;
}
}

return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}

///
/// 返回一个用于指定虚拟路径的缓存键。
///

///虚拟资源的路径。 ///
/// 所指定虚拟资源的缓存键。
///
public override string GetCacheKey(string virtualPath)
{
foreach (
var result in
this.fileProviders.Select(provider =&gt; provider.GetCacheKey(virtualPath)).Where(result =&gt; result != null))
{
return result;
}

return base.GetCacheKey(virtualPath);
}

///
/// 从虚拟文件系统中获取一个虚拟文件。
///

///虚拟文件的路径。 ///
/// 类的子代,该子代表示虚拟文件系统中的一个文件。
///
public override VirtualFile GetFile(string virtualPath)
{
foreach (var provider in this.fileProviders)
{
var file = provider.GetFile(virtualPath);
if (file != null)
{
return file;
}
}

return base.GetFile(virtualPath);
}

///
/// 返回指定虚拟路径的哈希值。
///

///主虚拟资源的路径。 ///一个路径数组,所包含的路径指向主要虚拟资源需要的其他虚拟资源。 ///
/// 指定虚拟路径的哈希值。
///
public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
{
foreach (
var result in
this.fileProviders.Select(provider =&gt; provider.GetFileHash(virtualPath, virtualPathDependencies)).Where(
result =&gt; result != null))
{
return result;
}

return base.GetFileHash(virtualPath, virtualPathDependencies);
}
}
}

一开始进入这个方法 FileExists 判断文件是否存在,存在为true

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;

namespace ItCast.Foundation.Hosting
{
///
/// Locator which loads views using the project structure to enable runtime view edits.
///

///
/// Works as long as you have used the structure which is described in the namespace documentation.
///
public class PluginFileLocator : IViewFileLocator
{
private readonly string basePath;
private IEnumerable allowedFileExtensions;

///
/// Initializes a new instance of the class.
///

public PluginFileLocator()
{
this.basePath = Path.GetFullPath(HostingEnvironment.MapPath("~") + @"..");
}

#region IViewFileLocator Members

///
/// Get full path to a file
///

///Requested uri /// ~/Admin/Content/themes/Blog/Site.css
/// ~/Admin/Scripts/Blog/BlogAjax.js
/// ~/Admin/Views/Blog/Home/Index.cshtml
/// ~/Content/themes/Blog/Site.css
/// ~/Scripts/Blog/BlogAjax.js
/// ~/Views/Blog/Home/Index.cshtml
///
/// Full disk path if found; otherwise null.
///
public string GetFullPath(string uri)
{
var pathConfigs = PluginPathConfig.GetConfigs();
var fixedUri = uri;
if (fixedUri.StartsWith("~"))
{
fixedUri = VirtualPathUtility.ToAbsolute(uri);
}

var path = string.Empty;
foreach (var pattern in pathConfigs.Keys)
{
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
var match = regex.Match(fixedUri);
if (match.Length &gt; 0)
{
path = Regex.Replace(fixedUri, pattern, pathConfigs[pattern], RegexOptions.IgnoreCase);
path = string.Format("{0}\\{1}", this.basePath, path.Replace('/', '\\'));
break;
}
}

if (!this.IsFileAllowed(uri))
{
return null;
}

if (File.Exists(path))
{
return path;
}

return null;
}

///
/// Set extensions that are allowed to be scanned.
///

///File extensions without the dot. public void SetAllowedExtensions(IEnumerable fileExtensions)
{
this.allowedFileExtensions = fileExtensions;
}

///
/// determins if the found embedded file might be mapped and provided.
///

///Full path to the file /// true if the file is allowed; otherwise false.
protected virtual bool IsFileAllowed(string fullPath)
{
if (fullPath == null)
{
throw new ArgumentNullException("fullPath");
}

var extension = fullPath.Substring(fullPath.LastIndexOf('.') + 1);
return this.allowedFileExtensions.Any(x =&gt; x == extension.ToLower());
}

#endregion
}
}

然后再获取缓存

///
/// 返回一个用于指定虚拟路径的缓存键。
///

///虚拟资源的路径。 ///
/// 所指定虚拟资源的缓存键。
///
public override string GetCacheKey(string virtualPath)
{
foreach (
var result in
this.fileProviders.Select(provider =&gt; provider.GetCacheKey(virtualPath)).Where(result =&gt; result != null))
{
return result;
}

return base.GetCacheKey(virtualPath);
}

缓存没找到,从虚拟文件系统中获取一个虚拟文件

///
/// 从虚拟文件系统中获取一个虚拟文件。
///

///虚拟文件的路径。 ///
/// 类的子代,该子代表示虚拟文件系统中的一个文件。
///
public override VirtualFile GetFile(string virtualPath)
{
foreach (var provider in this.fileProviders)
{
var file = provider.GetFile(virtualPath);
if (file != null)
{
return file;
}
}

return base.GetFile(virtualPath);
}

就是这样一个流程…………………………….

 

资料:http://msdn.microsoft.com/zh-cn/library/system.web.hosting.virtualpathprovider(VS.80).aspx

 

源码:http://pan.baidu.com/s/1pJsgaIf

 

你可以看这篇文章:http://www.cnblogs.com/liek/p/3898168.html帮助你跟好的理解。

 

 

成都卖身,有成都的朋友,可以推荐工作吗?
手机:18244293044
yangwensb@gmail.com

产品的造势和借力

mikel阅读(951)

个人开发者有一膛热血为实现自已的一个想法甘心悄愿抛洒出去,可爱又可怜的人。

很多时候好酒也怕巷子深,不懂得造势和借力想在偌大的市场上能溅起点儿水花都难!

因此个人开发者创业要慎重,不是技术牛逼就能成功,这个买卖的世界谁懂得营销谁就把握主动!

如何造势?产品过硬那就从粉丝开始求质不求量,建立铁杆粉丝参与进来开发产品,参与感和归属感让人很舒服,也很容易主动传播,这就是造势,基于信任的口碑营销要比发硬广效果好并可持续性强。

如何借力?产品要有好的渠道去推广展示,借助微信、QQ空间、微博、应用市场的平台去宣传,增加分享功能让用户分享到各大媒体平台,借各个平台的人气推广自己的产品。

偏扏狂才能生存

mikel阅读(1084)

今天听到了两个人说自已,一个是范范,一个是 怪木西西

范范说很多人都说不可能有效果的方法,然后自已傻了吧唧的,美滋滋的狠狠执行,结果效果很好。

怪木西西说自已学广场锻炼身体,然后每天都研究学习最后成了广场大妈们的领舞,同样是从事微信营销一样从入门就一门心思研究学习到现在成为专家。

两个人都很有意思,都成为一个领域的专家,这不是偶然是必然,因为他们都肯专注一心学习执行。

同样今天不约而同的收到几个人说说上谈圈子的力量,不可否认获得巨人的肩膀可以让你有所助力,但是没有专注的自学能力和狠狠地执行力也未必成功。

太浮躁地自媒体圈子让能人们纷纷走上神坛,个性思想冲击得观众本不坚定的心动摇了,没了自我,反观范范、怪木西西人家会依然偏执地坚持该干啥干啥 。

大潮汹涌的时代,保持本心,有时候就应该偏执地狠狠坚持执行,大牛背后又有多少努力和坚持谁知道啊!

[转载]WinForms 实现气泡提示窗口 - Lonely Shadow - 博客园

mikel阅读(902)

[转载]WinForms 实现气泡提示窗口 – Lonely Shadow – 博客园.

【实例说明】
气泡提示因为他的美观又好被大多数用户所接收,用户所喜爱的就是程序员要实现的。
本实例实现了任务栏气泡提示,运行本实例,效果图如下所示:
1.png
单击提示、气泡提示就会显示,单击“关闭”气泡又会消失掉。
【关键技术】
本实例实现时用到了NotifyIcon控件的ShowBallonTip方法。
NotifyIcon控件表示在通知区域中创建图标的控件,其ShowBalloonTip方法用于在任务栏中持续显示具有指定标题、问题和图标的气球提示指定的时间,该方法的语法格式如下:

/**
 * 【NontifyIcon控件的ShowBallonTip方法语法如下:】
 *   void NontifyIcon.ShowBallonTip(int timeout,string tipTitle, string tipText, TollTipIcon tipIcon);
 * 参数及说明:
 *   timeout:表示气球提示显示的时间长度
 *   tipTitlt:表示在气球提示上显示的标题
 *   tipText:表示在气球提示上显示的文本
 *   tipIcon:表示气球提示的图标
 * */

NontifyIcon控件的ShowBallonTip方法语法

【设计过程】
 (1)打开Visual Studio,新建WinForm应用程序,命名为BubbleShowForm、
 (2)窗体布局如上面的效果图所示。
 (3)关键代码如下所示:

// 单击“提示”
private void btn_Show_Click(object sender, EventArgs e)
{
     this.notifyIcon.Visible = true; // 设置提示控件可见
     // 显示气泡提示,时间为1秒,内容为当前时间,图标为消息图标
     this.notifyIcon.ShowBalloonTip(1000, "当前时间:", DateTime.Now.ToLocalTime().ToString(), ToolTipIcon.Info);
}

// 单击“关闭”
private void btn_Close_Click(object sender, EventArgs e)
{
     this.notifyIcon.Visible = false; // 设置提示控件隐藏
}

关键代码

[转载]Android的webview 加载数据时显示进度条,加载完后再把进度条取消并显示内容_chenchen132_新浪博客

mikel阅读(1277)

[转载]webview 加载数据时显示进度条,加载完后再把进度条取消并显示内容_chenchen132_新浪博客.

webview 加载数据时显示进度条有两种.
第一种方法
这个是加载数据时显示进度条
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS); 
setContentView(R.layout.main);

cWebView = (WebView) findViewById(R.id.Conditions);
   cWebView.getSettings().setJavaScriptEnabled(true);
   cWebView.getSettings().setSupportZoom(true);       
   cWebView.getSettings().setBuiltInZoomControls(true);
   
url = "http://site.baidu.com/";
cWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
// Activity和Webview根据加载程度决定进度条的进度大小
// 当加载到100%的时候 进度条自动消失
setTitle("Loading...");
setProgress(progress * 100);
}
});
cWebView.loadUrl(url);

第二种方法
这个是加载数据时显示ProgressDialog


class MyWebViewClient extends WebViewClient{

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}

@Override
public void onPageFinished(WebView view, String url) {
if(progressBar.isShowing()){
progressBar.dismiss();
}
}

@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
Toast.makeText(EnterListenter.this, "网页加载出错!", Toast.LENGTH_LONG);
alertDialog.setTitle("ERROR");
alertDialog.setMessage(description);
alertDialog.setButton("OK", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
alertDialog.show();
}
}
protected void initWebView(){
//设计进度条
progressBar = ProgressDialog.show(EnterListenter.this, null, "正在进入网页,请稍后…");
//获得WebView组件
cWebView = (WebView) findViewById(R.id.Conditions);
   cWebView.getSettings().setJavaScriptEnabled(true);
   cWebView.getSettings().setSupportZoom(true);       
   cWebView.getSettings().setBuiltInZoomControls(true);
   url = "http://site.baidu.com/";
   cWebView.loadUrl(url);
alertDialog = new AlertDialog.Builder(this).create();
//设置视图客户端
cWebView.setWebViewClient(new MyWebViewClient());
}