一、
SuppressLint
1)
SuppressLint
Lint是一个静态检查器,它围绕Android项目的正确性、安全性、性能、可用性以及可访问性进行分析。
它检查的对象包括XML资源、位图、ProGuard配置文件、源文件甚至编译后的字节码。
Lint包含了API版本检查、性能检查以及其他诸多特性。
可以使用
@SuppressLint
标注忽略指定的警告。
如果想去掉的话,可以右键点工程,然后在android tools 中,选择 clear lint marker 就没有这个错误了
其实,既然程序会报出这样的警告,肯定就会有他的不合理之处,只是并不会导致程序发生错误无法运行,我们写的代码平时也不多,所以一般对我们的程序不会有多大的影响,但是他会影响整个程序的安全性及一些其他性能,所以我们还是尽量去避免这写不合理之处。
2)
@SuppressLint
("NewApi")
我们有时会使用比我们在AndroidManifest中设置的android:minSdkVersion版本更高的方法,此时编译器会提示警告,解决方法是在方法上加上@SuppressLint("NewApi")或者@TargetApi()。
@SuppressLint("NewApi")屏蔽一切新api中才能使用的方法报的android lint错误
@TargetApi() 只屏蔽某一新api中才能使用的方法报的android lint错误
举个例子,某个方法中使用了api9新加入的方法,而项目设置的android:minSdkVersion=8,此时在方法上加@SuppressLint("NewApi")和@TargetApi(Build.VERSION_CODES.GINGERBREAD)都可以,以上是通用的情况。
而当你在此方法中又引用了一个api11才加入的方法时,@TargetApi(Build.VERSION_CODES.GINGERBREAD)注解的方法又报错了,而@SuppressLint("NewApi")不会报错,这就是区别。
注意,不管你使用了哪个注解,作用仅仅是屏蔽android lint错误,所以在方法中还要根据api的版本进行判断版本做不同的操作。
3)@SuppressLint("DrawAllocation")
我们从警告的提示来看,Avoid object allocations during draw/layout operations (preallocate and reuse instead),意为
避免在绘制/布局中去实例化对象,
解决办法:将这些对象改为类的成员变量。
因为在View及其子类的onDraw(Canvas canvas)方法,会实时调用以更新界面,会频繁的创建对象和进行垃圾回收等,这明显就会影响UI的显示性能,这样一个显示很顺畅的用户界面就会因对象分配引起的一些垃圾回收机制进行短暂的停滞。
4)@SuppressLint("HandlerLeak")
在主线程用Handler处理消息出现时会有警告,提示你,这块有内存泄露的危险,handler最好声明为static的
5)@SuppressLint("CommitPrefEdits")
sharedPreferences.edit()时,获取到的Editor必须使用commit或apply来完成操作。所以再没有写commit或apply之前或提示@SuppressLint("CommitPrefEdits");
Editor的commit和apply相比,apply效率跟高,commit方法返回boolean类型,判断是否存储成功。
简略解释:apply先将数据存储到内存,再异步操作存储到磁盘,而commit:写数据时就同步写到磁盘中了,所以效率会低一些。
6)@SuppressLint("RestrictedApi")
受限制的API,那应该还存在其他的替代方式,就尽量不要使用。
7)@SuppressLint(“SimpleDateFormat”)
不规范写法:SimpleDateFormat format = new SimpleDateFormat(pattern);
正确写法:SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.getDefault());
8)@SuppressLint(“DefaultLocale”)
不规范写法:String lower = string.toLowerCase();
boolean b = “String”.toUpperCase().equals(“STRING”);
正确写法:String lower = string.toLowerCase(Locale.getDefault());
boolean b = “String”.toUpperCase().equals(“STRING”);
二、
@SuppressWarnings
一、SuppressLint1)SuppressLintLint是一个静态检查器,它围绕Android项目的正确性、安全性、性能、可用性以及可访问性进行分析。它检查的对象包括XML资源、位图、ProGuard配置文件、源文件甚至编译后的字节码。Lint包含了API版本检查、性能检查以及其他诸多特性。可以使用@SuppressLint标注忽略指定的警告。如果想去掉的话,可以右键点工程...
一直没有用过注解方式,查了下,
L
int
是一个静态检查器,它围绕
Android
项目的正确性、安全性、性能、可用性以及可访问性进行分析。它检查的对象包括XML资源、位图、ProGuard配置文件、源文件甚至编译后的字节码。
这一版本的L
int
包含了API版本检查、性能检查以及其他诸多特性。其中还有一个重要的改动是L
int
可
@
Supp
re
ssL
int
或者@
Supp
re
ss
Warnings
黄色警告,虽然不去处理程序依然能够运行,但是实际上,解决这些问题往往会提高程序的安全性、可用性、性能等。转:https://blog.csdn.net/pangjl1982/article/details/86699164L
int
是一个静态检查器,它围绕
Android
项目的正确性、安全性、性能、可用性以及可访问性进行分析。
它检查的对象包括XML资源、位图、ProGuard配置文件、源文件甚至编译后的字节码。
L
int
包含了API版本检查、性能
>警告提示
Avoid object allocations during draw/layout operations (preallocate and reuse instead) le
ss
... (Ctrl+F1)
You should avoid allocating objects during a draw...
构建:Java 8和Apache Maven。
使用:Java 6,Java 7或Java 8(取决于组件)。
没有捆绑或计划捆绑ext-gson依赖项,因此应该将所有依赖项与provided作用域一起添加。
介绍了什么
当前ext-gson支持:
JsonReader和JsonWriter的次要实用程序方法。
JsonElement静态工厂方法和生成器, JsonElement合并方法。
参数化类型参数解析器和简单集合/映射类型工厂方法。
特殊类型的适配器和工厂:
AbstractBoundTypeAdapterFactory绑定到特定类型的类型适配器工厂超类,以摆脱@
Supp
re
ss
Warnings
("unchecked")样板;
AlwaysListType
Meet detekt, a static code analysis tool for the Kotlin programming language.
It operates on the abstract syntax tree provided by the Kotlin compiler.
Features
Code smell analysis for your Kotlin projects
Complexity report based on logical lines of code, McCabe complexity and amount of code smells
Highly configurable
Supp
re
ss
findings with Kotlin's @
Supp
re
ss
and Java's @
Supp
re
ss
Warnings
annotations
Specify code smell thresholds to break your build
Code Smell baseline and igno
RSA前端JS加密,后端JAVA解密实现
用RSA非对称加密方式实现。后台生成rsa密钥对,然后在页面设置rsa公钥,提交时用公钥加密密码,生成的密文传到后台,后台再用私钥解密,获取密码明文。
这样客户端只需要知道rsa加密方式和公钥,前台不知道私钥是无法解密的,此解决方案还是相对比较安全的。
需要到http://www.bouncycastle.org/latest_releases.html下载bcpkix-jdk15on-151.jar文件。
缺陷:由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论 是软件还是硬件实现。所以一般来说只用于少量数据 加密。
下面我们就来一个实际的例子:
1、前端加密需要引入Barrett.js、Big
Int
.js和RSA.js。
<script src="/rsa/RSA.js" type="text/javascript"></script>
<script src="/rsa/Big
Int
.js" type="text/javascript"></script>
<script src="/rsa/Barrett.js" type="text/javascript"></script>
2、前端加密代码:
encryptedString : (function(paramStr, rsaKey){
setMaxDigits(130);
//第一个参数为加密指数、第二个参数为解密参数、第三个参数为加密系数
//加密指数就是RSA公有KEY对象对象中toString()返回的字符串(encryptionExponent)数字部分默认就是10001.
//加密系数就是RSA公有KEY对象对象中toString()返回的字符串modulus部分
key = new RSAKeyPair("10001", "", rsaKey);
//返回加密后的字符串
return encryptedString(key, encodeURIComponent(paramStr));
复制代码其中的加密系数可以自定义,这里为:8246a46f44fc4d961e139fd70f4787d272d374532f4d2d9b7cbaad6a15a8c1301319aa6b3f30413b859351c71938aec516fa7147b69168b195e81df46b6bed7950cf3a1c719d42175f73d7c97a85d7d20a9e83688b92f05b3059bb2ff75cd7190a042cd2db97ebc2ab4da366f2a7085556ed613b5a39c9fdd2bb2595d1dc23b5
3、后台RSA加密解密方法如下:
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.Big
Int
eger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.
int
erfaces.RSAPrivateKey;
import java.security.
int
erfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.lang.StringUtils;
import com.jd.uwp.common.Constants;
* RSA 工具类。提供加密,解密,生成密钥对等方法。
* 需要bcprov-jdk16-140.jar包。
public cla
ss
RSAUtil {
private static String RSAKeyStore = "RSAKey.txt";
//测试方法
public static void main(String[] args){
//先生成密钥文件
String basePath = "D:\\RSA\\";
RSAUtil.generateKeyPair(basePath);
//得到公用KEY对象,如果不保存到可以从生成密钥方法得到.
KeyPair kp = RSAUtil.getKeyPair(basePath);
//对字符串加密
String pa
ss
= "123456";
byte[] enpa
ss
= RSAUtil.encrypt(pk.getPublicKey(), pa
ss
.getByte())
String enpa
ss
Str = new String(enpa
ss
);
System.out.pr
int
ln("加密:" + enpa
ss
Str);
//对字符串解密--注意JAVA中解密要用byte[]这种方法
byte[] depa
ss
= RSAUtil.decrypt(pk.getPrivateKey(), enpa
ss
);
String depa
ss
Str = new String(depa
ss
);
System.out.pr
int
ln("解密:" + depa
ss
Str);
//对字符串解密--主要针对JS传过来的加密字符串解密,其内部也要调用上面的方法.
String decryptStr(String paramStr, String basePath)
//注意JS中用到的encryptionExponent和modulus通过pk.getPublicKey().toString()字符串中得到.
* * 生成密钥对
* @return KeyPair
* @throws EncryptException
public static KeyPair generateKeyPair(String basePath) throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
final
int
KEY_SIZE = 1024;
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
saveKeyPair(keyPair, basePath);
return keyPair;
} catch (Exception e) {
throw new Exception(e.getMe
ss
age());
* 获取密钥对
* @return
* @throws Exception
public static KeyPair getKeyPair(String basePath) throws Exception {
FileInputStream fis = new FileInputStream(StringUtils.isNotBlank(basePath) ? (basePath + RSAKeyStore) : RSAKeyStore);
ObjectInputStream oos = new ObjectInputStream(fis);
KeyPair kp = (KeyPair) oos.readObject();
oos.close();
fis.close();
return kp;
* 保存密钥
* @param kp
* @throws Exception
public static void saveKeyPair(KeyPair kp, String basePath) throws Exception {
FileOutputStream fos = new FileOutputStream(StringUtils.isNotBlank(basePath) ? (basePath + RSAKeyStore) : RSAKeyStore);
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 生成密钥
oos.writeObject(kp);
oos.close();
fos.close();
* * 生成公钥
* @param modulus
* @param publicExponent
* @return RSAPublicKey
* @throws Exception
public static RSAPublicKey generateRSAPublicKey(byte[] modulus,
byte[] publicExponent) throws Exception {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new Exception(ex.getMe
ss
age());
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new Big
Int
eger(
modulus), new Big
Int
eger(publicExponent));
try {
return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
} catch (InvalidKeySpecException ex) {
throw new Exception(ex.getMe
ss
age());
* * 生成私钥
* @param modulus
* @param privateExponent
* @return RSAPrivateKey
* @throws Exception
public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,
byte[] privateExponent) throws Exception {
KeyFactory keyFac = null;
try {
keyFac = KeyFactory.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
} catch (NoSuchAlgorithmException ex) {
throw new Exception(ex.getMe
ss
age());
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new Big
Int
eger(
modulus), new Big
Int
eger(privateExponent));
try {
return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
} catch (InvalidKeySpecException ex) {
throw new Exception(ex.getMe
ss
age());
* * 加密
* @param key 加密的密钥
* @param data 待加密的明文数据
* @return 加密后的数据
* @throws Exception
public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, pk);
// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
int
blockSize = cipher.getBlockSize();
// 加密块大小为127byte,加密后为128个byte;
//因此共有2个加密块,第一个127byte第二个为1个byte
int
outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
int
leavedSize = data.length % blockSize;
int
block
sS
ize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
byte[] raw = new byte[outputSize * block
sS
ize];
int
i = 0;
while (data.length - i * blockSize > 0) {
if (data.length - i * blockSize > blockSize) {
cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
} else {
cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
return raw;
} catch (Exception e) {
throw new Exception(e.getMe
ss
age());
* * 解密
* @param key 解密的密钥
* @param raw 已经加密的数据
* @return 解密后的明文
* @throws Exception
@
Supp
re
ss
Warnings
("static-acce
ss
")
public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, pk);
int
blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int
j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
return bout.toByteArray();
} catch (Exception e) {
throw new Exception(e.getMe
ss
age());
* 解密方法
* paramStr ->密文
* basePath ->RSAKey.txt所在的文件夹路径
public static String decryptStr(String paramStr, String basePath) throws Exception{
byte[] en_result = new Big
Int
eger(paramStr, 16).toByteArray();
byte[] de_result = decrypt(getKeyPair(basePath).getPrivate(), en_result);
StringBuffer sb = new StringBuffer();
sb.append(new String(de_result));
//返回解密的字符串
return sb.reverse().toString();
4、前端提交到后端解密调用: //前端 表单提交
$.ajax({
url : contextPath + "test.action",
//加密传输,第二个参数应该是从ACTION传过来才对.
data : {pwd:encryptedString ($("#pwd").val(), "adasdasdasdasdadsasdasdasdasd")},
type : "post",
datatype : "json",
succe
ss
: function(retData){
//后端解密代码
RSAUtil.decryptStr(paramMap.getString("pwd"), request.getSe
ss
ion().getServletContext().getRealPath("/"));
dom4j,jsoup,jdom,w3cdom,xstream使用代码工程
package ivyy.taobao.com.dom4j;
import ivyy.taobao.com.entity.Addre
ss
;
import ivyy.taobao.com.entity.Location;
import ivyy.taobao.com.entity.Po
int
;
import ivyy.taobao.com.entity.Pois;
import ivyy.taobao.com.utils.IoUtils;
import ivyy.taobao.com.utils.UrlUtils;
import ivyy.taobao.com.utils.Dom4jUtils;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
*@Date:2015-1-6
*@Author:liangjilong
*@Email:jilongliang@sina.com
*@Version:1.0
*@Description:
@
Supp
re
ss
Warnings
("all")
public cla
ss
Dom4jTest2 {
public static void main(String[] args)throws Exception {
//String filepath="D:/"+System.currentTimeMillis()+".xml";
String filepath="D:/test/map1.xml";
File f=new File(filepath);
if(!f.exists()){
f.createNewFile();
//List<Pois> list=getReaderXml("URL");
List<Pois> list=getReaderXml("FILE");
org.dom4j.Document doc=createAsXML(list);
IoUtils.write(doc.asXML(),filepath);
//格式化
Dom4jUtils.formatAsXml(doc);
/****
* 组装成一个xml
* @param list
* @return
* @throws Exception
private static org.dom4j.Document createAsXML(List<Pois> list) throws Exception{
org.dom4j.Document doc=DocumentHelper.createDocument();
Element root=doc.addElement("GeocoderSearchResponse");//根
root.addElement("status").setText("0");//status
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Pois pois = (Pois) iterator.next();
Element result=root.addElement("result");//result
List<Location> listLoc=pois.getLocations();
Element location=result.addElement("location");//location
for (Iterator iterator2 = listLoc.iterator(); iterator2.hasNext();) {
Location locObj = (Location) iterator2.next();
location.addElement("lat").setText(locObj.getLat()+"");//lat
location.addElement("lng").setText(locObj.getLng()+"");//lat
result.addElement("formatted_addre
ss
").setText(locObj.getFormattedAddre
ss
()+"");//formatted_addre
ss
result.addElement("busine
ss
").setText(locObj.getBusine
ss
()+"");//busine
ss
List<Addre
ss
> listAdd=pois.getAddre
ss
();
Element comp=result.addElement("addre
ss
Component");//addre
ss
Component
for (Iterator iterator3 = listAdd.iterator(); iterator3.hasNext();) {
Addre
ss
addre
ss
= (Addre
ss
) iterator3.next();
comp.addElement("streetNumber").setText(addre
ss
.getStreetNumber()+"");//streetNumber
comp.addElement("street").setText(addre
ss
.getStreet()+"");//street
comp.addElement("district").setText(addre
ss
.getDistrict()+"");//district
comp.addElement("city").setText(addre
ss
.getCity()+"");//city
comp.addElement("province").setText(addre
ss
.getProvince()+"");//province
comp.addElement("cityCode").setText(addre
ss
.getCityCode()+"");//cityCode
Element poi=result.addElement("pois").addElement("poi");
poi.addElement("addr").setText(pois.getAddr());//addr
poi.addElement("distance").setText(pois.getDistance());//distance
poi.addElement("name").setText(pois.getName());//name
poi.addElement("poiType").setText(pois.getPoiType());//poiType
poi.addElement("tel").setText(pois.getTel());//tel
poi.addElement("zip").setText(pois.getZip());//zip
List<Po
int
> listPo
int
=pois.getPo
int
s();
Element po
int
=poi.addElement("po
int
");
for (Iterator iterator4 = listPo
int
.iterator(); iterator4.hasNext();) {
Po
int
p = (Po
int
) iterator4.next();
po
int
.addElement("x").setText(p.getX()+"");
po
int
.addElement("y").setText(p.getY()+"");
return doc;
* Dom4j(SAX)读取xml数据(解析)
* @param params
* @throws Exception
private static List<Pois> getReaderXml(String flg) throws Exception{
String fromRead=Dom4jTest2.cla
ss
.getCla
ssL
oader().getResource("xml/map1.xml").getPath();
List<Pois> list=new ArrayList<Pois>();
SAXReader saxReader = new SAXReader();
org.dom4j.Document document=null;
//从api上面解析
if(flg.equals("URL")){
String url = UrlUtils.getBaiduMapUrl("你的key", "39.983424,116.322987", "xml");
document = saxReader.read(url);
//从文件上面的xml解析
}else if(flg.equals("FILE")){
document = saxReader.read(new File(fromRead));
Element resultEl = (Element)document.getRootElement().element("result");
Element poisEl=resultEl.element("pois");//pois节点
Element locationEl=resultEl.element("location");//location节点
Element addre
ss
El=resultEl.element("addre
ss
Component");//addre
ss
Component节点
/*******从pois节点下面遍历多个poi节点*******/
for (Iterator<Element> poIter = poisEl.elementIterator("poi"); poIter.hasNext();) {
Element element = (Element) poIter.next();
String addr = element.elementText("addr");
String distance = element.elementText("distance");
String name = element.elementText("name");
String poiType = element.elementText("poiType");
String tel =(element.elementText("tel")==""?"":element.elementText("tel"));
String zip =(element.elementText("zip")==""?"":element.elementText("zip"));
Pois poi=new Pois();
poi.setAddr(addr);
poi.setDistance(distance);
poi.setName(name);
poi.setPoiType(poiType);
poi.setTel(tel);
poi.setZip(zip);
List<Location> listLoc=new ArrayList<Location>();
/************Location***************************/
String busine
ss
=resultEl.elementText("busine
ss
");
String formatted_addre
ss
=resultEl.elementText("formatted_addre
ss
");
String lat = locationEl.elementText("lat");
String lng = locationEl.elementText("lng");
Location location=new Location();
location.setBusine
ss
(busine
ss
);
location.setFormattedAddre
ss
(formatted_addre
ss
);
location.setLat(lat);
location.setLng(lng);
listLoc.add(location);
poi.setLocations(listLoc);
List<Addre
ss
> listAddr=new ArrayList<Addre
ss
>();
/************Addre
ss
***************************/
Addre
ss
addre
ss
=new Addre
ss
();
String streetNumber=(addre
ss
El.elementText("streetNumber")==""?"":addre
ss
El.elementText("streetNumber"));
String street=(addre
ss
El.elementText("street")==""?"":addre
ss
El.elementText("street"));
String district=(addre
ss
El.elementText("district")==""?"":addre
ss
El.elementText("district"));
String city=(addre
ss
El.elementText("city")==""?"":addre
ss
El.elementText("city"));
String province=(addre
ss
El.elementText("province")==""?"":addre
ss
El.elementText("province"));
String direction=(addre
ss
El.elementText("direction")==""?"":addre
ss
El.elementText("direction"));
String distancez=(addre
ss
El.elementText("distance")==""?"":addre
ss
El.elementText("distance"));
addre
ss
.setStreetNumber(streetNumber);
addre
ss
.setStreet(street);
addre
ss
.setCity(city);
addre
ss
.setDistrict(district);
addre
ss
.setDirection(direction);
addre
ss
.setDistance(distancez);
addre
ss
.setProvince(province);
listAddr.add(addre
ss
);
poi.setAddre
ss
(listAddr);
list.add(poi);
return list;
最近用到handle在线程中改变UI,会跟给出“This Handler cla
ss
should be static or leaks might occur”的警告,网上看了很多解决办法,但都不够详细,这里我重新写一下这个问题的解决办法。
1.问题原因:在ADT 20 Changes我们可以找到这样一个变化:“New L
int
Checks: Look for handler leaks