最近项目的功能需要用到扫描二维码.就参考了google的开源项目ZXing..功能完成后..发现扫条形码没有问题..但是扫描二维码的时候却有一部分是乱码..或者不是中文的问题..于网上参考了很资料.但效果还是不太理想..后来发现只要以ISO-
8859
-
1
的格式来编码,取出结果再进行相应的转换..问题就解决了.并不需要修改源码:以下是修改的方法
第一:先在CaptureActivity类中设置它的默认编码
第二:你在取回结果的Activity中转换相应的编码.这里我是在ResultActivity类里作处理的
第三:以下就是判断是否在Unicode编码里
最后这样就解决了ZXing的中文乱码问题.
From: http://mobile.51cto.com/iphone-274085.htm
本节主题包括Cocoa命名约定以及我们提倡的框架编程实践。使用公共API开发Cocoa框架、插件及其他可执行文件需要使用的方法和约定不同于应用程序开发。如果产品主要客户是开发人员,则保证产品的编程接口清晰明确,不至于让开发者产生疑惑十分重要。
这种情况下,API命名约定就可以派上用场,它可以帮助您保持编程接口一致明确。另外,框架开发领域也存在一些特定的编程技术—或者说,这些技术对框架开发更加重要—例如版本管理,二进制兼容性,错误处理以及内存管理等。
在面向对象软件库的设计过程中,开发人员经常忽视对类、方法、函数、常量以及其他编程接元素的命名。本节讨论大多数Cocoa接口通用的几条命名约定。
一般性原则清晰
最好是既清晰又尽可能地简短,但不要为了追求简短而丧失清晰性:
通常情况下,请不要缩写事物的名称,即使名称很长,也应该把它完全拼写出来。
您可能觉得某个缩写众所周知,但实际可能并非如此。特别是具有不同文化和语言背景的开发人员,在遇到您提供的方法或函数的名称缩写时,他们可能不明白其中的含义。
不过,有一些缩写确实很常见并且有很长的使用历史。因此,您可以继续使用。请参看“可以接受的缩略名称”一节以了解更多的信息。
要防止API的名称出现歧义。这里的歧义是指名称具有多种解释方式。
sendPort:该方法是把端口发送出去还是返回发送端口呢?
displayName:该方法是显示某个名称还是返回用户界面中接收者的标题呢?
一致性
请尽可能在Cocoa编程接口中保持名称一致性。如果不太有把握做到这一点,则请浏览一下头文件和参考文档中的范例。
如果类方法利用多态,一致性就显得尤其重要。因为在这种情况下,不同类用于完成同样事件的方法必须具有相同的名称。
您可以参看 “方法参数”一节。
不能自我指涉
名称不应该自我指涉。
NSString:可以使用
NSStringObject:该名称自我指涉
掩码的常量(可以使用位操作进行组合)不适用这条规则,作为通告的常量也不适用。
前缀
前缀是编程接口名称的重要部分,它们可以区分软件的功能范畴。通常情况下,提供编程接口的软件会被打包成框架(Foundation 框架以及 Application Kit框架就是如此)或者是和框架紧密相关的产品,我们可以利用前缀来区分框架的功能范畴。另外,前缀可以防止第三方开发者定义的符号和苹果公司定义的符 号发生冲突(以及防止苹果公司不同框架之间的符号发生冲突)。
前缀有规定的格式。它需要由两个或者三个大写字符组成,而且不能使用下划线或者“子前缀”。下面是一些例子:
在为类,协议,函数,常量以及通过typedef定义的结构命名时,请使用前缀。但在命名方法时,请不要使用前缀,因为方法已经存在于其定义类所创建的名称空间中。同理,在定义结构的字段时,也不要使用前缀。
书写约定
为API元素命名的时候, 请遵循下面这几条简单的书写约定:
对于含有多个单词的名称,请不要使用标点符号标志和分割符(下划线,破折号之类);而是要大写每个单词的首字符并且把这些单词连续地拼写在一起。然而如下这些限定条件您也需要注意:
方法的名称要以一个小写字符开头,而名称中单词的首字符应该大写。另外,请不要在方法的名称中使用前缀。
如果方法名称的开头是某个众所周知的缩略语,则该原则就不适用。例如TIFFRepresentation (NSImage),该名称就不遵循该原则。
函数或常量名称使用其关联类的前缀,并且要名称中单词的首字符要大写。
请不要使用下划线作为前缀来表示私有的属性,尤其是不要在类方法中使用。因为苹果公司保留使用这种方式,如果第三方再使用,就有可能会导致名称空间 冲突。他们有可能在无意中用自己的方法覆盖了一个已经存在的私有方法,这样做将会带来灾难性的后果。请参看“私有方法”一节。您可以了解到我们提倡的可供 私有API使用的约定。
类和协议的名称
类的名称应包含一个名词,这个名词明确地指示这个类(或者类对象)表示什么或者要做什么。此外,类名称还应该包含适当的前缀。(请参考“前缀”一 节)。Foundation框架以及Application Kit框架就有很多这样的例子,例如NSString, NSDate,NSScanner,NSApplication,NSButton, 以及NSEvent。
我们应根据协议对方法的分组方式来为其命名:
大部分协议会把一些彼此相关但又不合类关联的方法归结在一起,形成一个特殊的方法集合。这种协议要合理地命名,不要将其和类名混淆。一种常见的约定是使用动名词格式(“...ing”):
有一些协议会把一些彼此无关的方法归结在一起(不是创建几个独立的小协议)。对于这样的协议,我们倾向于把它和一个类联系起来,利用类来作为协议的主要表现。并且,我们约定让此种协议使用和类一样的名称。
NSObject协议就是这种情况。它把一些不相关的方法组合在一起,这些方法有的用于查询任何对象在类层次中的位置,有的可以调用对象的特定方 法,有的可以用来增加或者减少对象的引用计数。由于NSObject类提供了这些方法的主要表现,所以我们使用类名作为协议名称。
头文件
头文件的命名方式很重要,因为通过使用合理的命名约定,您利用文件名称来指示文件中包含的内容:
声明一个独立的类或协议。.如果一个类或协议不属于某个群,则请将其声明放置在一份独立的文件,并使用其名称作为文件名。
声明相关联的类或者协议:如果一群声明(类,类别以及协议)彼此相关,则请将它们放在一份文件,并使用主要的类或者协议名称作为文件名。
包含框架头文件。每个框架都应该包含一份头文件,它的名称和框架名相同,而内容则包含了框架的全部公共头文件。
为另一个框架里的某个类添加API。如果您在一个框架中声明一些方法,而这些方法属于另一个框架中某个类的范畴类,则请在原始类的名称后加上“Additions”,然后将其作为头文件的名称。例如Application Kit框架中的NSBundleAdditions.h头文件就是这种处理方式。
相关联的函数和数据类型。如果一群函数,常量,结构以及其他数据类型彼此相互关联,则请将它们放入到合理命名的头文件,例如NSGaphics.h(位于Application Kit)。
小结:关于Cocoa 编码指南 代码命名基础的内容介绍完了,希望本文对你有所帮助!关于Cocoa 编码指南的更多内容,请参考以下几篇文章。
Cocoa 编码指南 代码命名基础: http://mobile.51cto.com/iphone-274085.htm
Cocoa 编码指南 为函数命名: http://www.51cto.com/php/viewart.php?artID=274108
Cocoa 编码指南 为方法命名: http://www.51cto.com/php/viewart.php?artID=274104
Cocoa 编码指南 为实例变量和数据类型命名:http://www.51cto.com/php/viewart.php?artID=274094
Cocoa 编码指南 框架开发者使用技巧和技术http://www.51cto.com/php/viewart.php?artID=274094
无论大型或小型应用,灵活的缓存可以说不仅大大减轻了服务器的压力,而且因为更快速的用户体验而方便了用户。
Android的apk可以说是作为小型应用,其中99%的应用并不是需要实时更新的,而且诟病于蜗牛般的移动网速,与服务器的数据交互是能少则少,这样用户体验才更好,这也是我们有时舍弃webview而采用json传输数据的原因之一。
采用缓存,可以进一步大大缓解数据交互的压力,特此,我们简略列举一下缓存管理的适用环境:
1. 提供网络服务的应用
2. 数据更新不需要实时更新,但是哪怕是3-5分钟的延迟也是可以采用缓存机制。
3. 缓存的过期时间是可以接受的(不会因为缓存带来的好处,导致某些数据因为更新不及时而影响产品的形象等)
带来的好处:
1. 服务器的压力大大减小
2. 客户端的响应速度大大变快(用户体验)
3. 客户端的数据加载出错情况大大较少,大大提高了应有的稳定性(用户体验)
4. 一定程度上可以支持离线浏览(或者说为离线浏览提供了技术支持)
一、缓存管理的方法
这里的缓存管理的原理很简:通过时间的设置来判断是否读取缓存还是重新下载。
里面会有一些细节的处理,后面会详细阐述。
基于这个原理,目前鄙人见过的两种比较常见的缓存管理方法是:数据库法和文件法。
二、数据库法缓存管理
这种方法是在下载完数据文件后,把文件的相关信息如url,路经,下载时间,过期时间等存放到数据库,下次下载的时候根据url先从数据库中查询,如果查询到当前时间并未过期,就根据路径读取本地文件,从而实现缓存的效果。
从实现上我们可以看到这种方法可以灵活存放文件的属性,进而提供了很大的扩展性,可以为其它的功能提供一定的支持;
从操作上需要创建数据库,每次查询数据库,如果过期还需要更新数据库,清理缓存的时候还需要删除数据库数据,稍显麻烦,而数据库操作不当又容易出现一系列的性能,ANR问题,实现的时候要谨慎,具体作的话,但也只是增加一个工具类或方法的事情。
还有一个问题,缓存的数据库是存放在/data/data/<package>/databases/目录下,是占用内存空间的,如果缓存累计,容易浪费内存,需要及时清理缓存。
当然这种方法从目前一些应用的实用上看,我没有发现什么问题。
本文我侧重强调第二种方法,第一种方法的实现,就此掠过。
三、文件法缓存管理
这种方法,使用File.lastModified()方法得到文件的最后修改时间,与当前时间判断是否过期,从而实现缓存效果。
实现上只能使用这一个属性,没有为其它的功能提供技术支持的可能。
操作上倒是简单,比较时间即可。本身处理也不容易带来其它问题,代价低廉。
四、文件法缓存管理的两点说明
1. 不同类型的文件的缓存时间不一样。
笼统的说,不变文件的缓存时间是永久,变化文件的缓存时间是最大忍受不变时间。
说白点,图片文件内容是不变的,直到清理,我们是可以永远读取缓存的。
配置文件内容是可能更新的,需要设置一个可接受的缓存时间。
2. 不同环境下的缓存时间标准不一样。
无网络环境下,我们只能读取缓存文件,哪怕缓存早就过期。
WiFi网络环境下,缓存时间可以设置短一点,一是网速较快,而是流量不要钱。
移动数据流量环境下,缓存时间可以设置长一点,节省流量,就是节省金钱,而且用户体验也更好。
举个例子吧,最近本人在做的一个应用在wifi环境下的缓存时间设置为5分钟,移动数据流量下的缓存时间设置为1小时。
这个时间根据自己的实际情况来设置:数据的更新频率,数据的重要性等。
五、何时刷新
开发者一方面希望尽量读取缓存,用户一方面希望实时刷新,但是响应速度越快越好,流量消耗越少越好,是一个矛盾。
其实何时刷新我也不知道,这里我提供两点建议:
1. 数据的最长多长时间不变,对应用无大的影响。
比如,你的数据更新时间为1天,则缓存时间设置为4~8小时比较合适,一天他总会看到更新,如果你觉得你是资讯类应用,再减少,2~4小时,如果你觉得数据比较重要或者比较受欢迎,用户会经常把玩,再减少,1~2小时,依次类推。
为了保险起见,你可能需要毫无理由的再次缩减一下。
2. 提供刷新按钮。
上面说的保险起见不一定保险,最保险的方法使在相关界面提供一个刷新按钮,为缓存,为加载失败提供一次重新来过的机会,有了这个刷新按钮,我们的心也才真的放下来。
六、文件缓存法的具体实现
针对配置文件的缓存,我新建了一个类ConfigCache:
import java.io.File;
import java.io.IOException;
import android.util.Log;
import com.tianxia.app.floworld.AppApplication;
import com.tianxia.app.floworld.utils.FileUtils;
import com.tianxia.app.floworld.utils.NetworkUtils;
public class ConfigCache {
private static final String TAG = ConfigCache.class.getName();
public static final int CONFIG_CACHE_MOBILE_TIMEOUT = 3600000; //1 hour
public static final int CONFIG_CACHE_WIFI_TIMEOUT = 300000; //5 minute
public static String getUrlCache(String url) {
if (url == null) {
return null;
}
String result = null;
File file = new File(AppApplication.mSdcardDataDir + "/" + getCacheDecodeString(url));
if (file.exists() && file.isFile()) {
long expiredTime = System.currentTimeMillis() - file.lastModified();
Log.d(TAG, file.getAbsolutePath() + " expiredTime:" + expiredTime/60000 + "min");
//1. in case the system time is incorrect (the time is turn back long ago)
//2. when the network is invalid, you can only read the cache
if (AppApplication.mNetWorkState != NetworkUtils.NETWORN_NONE && expiredTime < 0) {
return null;
}
if(AppApplication.mNetWorkState == NetworkUtils.NETWORN_WIFI
&& expiredTime > CONFIG_CACHE_WIFI_TIMEOUT) {
return null;
} else if (AppApplication.mNetWorkState == NetworkUtils.NETWORN_MOBILE
&& expiredTime > CONFIG_CACHE_MOBILE_TIMEOUT) {
return null;
}
try {
result = FileUtils.readTextFile(file);
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static void setUrlCache(String data, String url) {
File file = new File(AppApplication.mSdcardDataDir + "/" + getCacheDecodeString(url));
try {
//创建缓存数据到磁盘,就是创建文件
FileUtils.writeTextFile(file, data);
} catch (IOException e) {
Log.d(TAG, "write " + file.getAbsolutePath() + " data failed!");
e.printStackTrace();
}
}
public static String getCacheDecodeString(String url) {
//1. 处理特殊字符
//2. 去除后缀名带来的文件浏览器的视图凌乱(特别是图片更需要如此类似处理,否则有的手机打开图库,全是我们的缓存图片)
if (url != null) {
return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+");
}
return null;
}
}
从实现上我们全面考虑了几个细节,注释已经说明,不再赘述。
然后我们调用方法如下:
void getConfig(){
//首先尝试读取缓存
String cacheConfigString = ConfigCache.getUrlCache(CONFIG_URL);
//根据结果判定是读取缓存,还是重新读取
if (cacheConfigString != null) {
showConfig(cacheConfigString);
} else {
//如果缓存结果是空,说明需要重新加载
//缓存为空的原因可能是1.无缓存;2. 缓存过期;3.读取缓存出错
AsyncHttpClient client = new AsyncHttpClient();
client.get(CONFIG_URL, new AsyncHttpResponseHandler(){
@Override
public void onSuccess(String result){
//成功下载,则保存到本地作为后面缓存文件
ConfigCache.setUrlCache(result, CONFIG_URL);
//后面可以是UI更新,仅供参考
showConfig(result);
}
@Override
public void onFailure(Throwable arg0) {
//根据失败原因,考虑是显示加载失败,还是再读取缓存
}
});
}
}
这样配置文件既能有效缓存,又能及时更新了,同时支持离线浏览。
七、小结
智能手机的缓存管理应用非常的普遍和需要,是提高用户体验的有效手段之一。
当然,缓存管理一些内容没有细说,如图片缓存,缓存清理等,这些处理起来比较简单。