首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

接口自动化测试PHPUnit-框架代码开发1

经过上一篇的架构设计之后,我们就要开始编写代码了,因为涉及代码较多,所以将分多次进行讲解。 先看一张整体结构图 今天我们先来看看testcase文件里的编写。此处我们以之前的老黄历接口为例。 lhl_test.php内容如下: <?php //代码获取点击链接加入QQ群 522720170:https://jq.qq.com/?_wv=1027&k=5C08ATe //引入一些必要的文件,暂时别管,后面会说到 require_once("../commons/require.php"); use PHPUnitFrameworkTestCase; class LhlTest extends TestCase { //测试用例必须以 test 开头,否则 phpunit 不识别 public function testLhl() { //选择运行环境。此处把host配置到了文件中,直接读取文件内容 $rc=new ReadConfig(); $url=$rc->get_host("online") ; echo $url; //拼接完整的请求串 $get_params="date=2017-11-11&key=填写你申请的key"; $url=$url."?".$get_params; $content=Transfer::get($url); //对返回的json结果进行编码,也就是转换为php可以认识的对象,方便后续使用 $data= json_decode($content,true); print_r($data); if(is_null($data)==false) { //断言,如果返回的error_code为0说明接口成功 $this->assertEquals('0',$data['error_code'],"failed"); print("successed"); } } } ?> 本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/1982675,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发8——利用pull解析器读写XML文件

一、基本介绍 对XML解析有SAX和DOM等多种方式,Android中极力推荐xmlpull方式解析xml。xmlpull不仅可用在Android上同样也适用于javase,但在javase环境中需自己获取xmlpull所依赖的类库,kxml2-2.3.0.jar,xmlpull_1_1_3_4c.jar。 jar包下载网址http://www.xmlpull.org/http://kxml.sourceforge.net/ 二、例子 读取到xml的声明返回数字0 START_DOCUMENT; 读取到xml的结束返回数字1 END_DOCUMENT ; 读取到xml的开始标签返回数字2 START_TAG 读取到xml的结束标签返回数字3 END_TAG 读取到xml的文本返回数字4 TEXT <?xmlversion="1.0"encoding="UTF-8"?> <people> <personid="001"> <name>XY1</name> <age>22</age> </person> <personid="002"> <name>XY2</name> <age>22</age> </person> </people> packagecn.xy.service; importjava.io.InputStream; importjava.io.OutputStream; importjava.util.ArrayList; importjava.util.List; importorg.xmlpull.v1.XmlPullParser; importorg.xmlpull.v1.XmlSerializer; importandroid.util.Xml; importcn.xy.model.Person; publicclassPersonService { publicListgetPeople(InputStreamxml)throwsException { Listlst=null; Personperson=null; //利用ANDROID提供的API快速获得pull解析器 XmlPullParserpullParser=Xml.newPullParser(); //设置需要解析的XML数据 pullParser.setInput(xml,"UTF-8"); //取得事件 intevent=pullParser.getEventType(); //若为解析到末尾 while(event!=XmlPullParser.END_DOCUMENT)//文档结束 { StringnodeName=pullParser.getName(); switch(event) { caseXmlPullParser.START_DOCUMENT://文档开始 lst=newArrayList(); break; caseXmlPullParser.START_TAG://标签开始 if("person".equals(nodeName)) { Stringid=pullParser.getAttributeValue(0); person=newPerson(); person.setId(id); } if("name".equals(nodeName)) { Stringname=pullParser.nextText(); person.setName(name); } if("age".equals(nodeName)) { intage=Integer.valueOf(pullParser.nextText()); person.setAge(age); } break; caseXmlPullParser.END_TAG://标签结束 if("person".equals(nodeName)) { lst.add(person); person=null; } break; } event=pullParser.next();//下一个标签 } returnlst; } publicvoidsaveDataToXML(OutputStreamos,Listlst)throwsException { XmlSerializerxs=Xml.newSerializer(); xs.setOutput(os,"UTF-8"); xs.startDocument("UTF-8",true); xs.startTag(null,"people"); for(Personp:lst) { xs.startTag(null,"person"); xs.attribute(null,"person",p.getId()); xs.startTag(null,"name"); xs.text(p.getName()); xs.endTag(null,"name"); xs.startTag(null,"age"); xs.text(p.getAge().toString()); xs.endTag(null,"age"); xs.endTag(null,"person"); } xs.endTag(null,"people"); xs.endDocument(); os.flush(); os.close(); } } publicclassTestClassextendsAndroidTestCase { publicvoidtestPeople()throwsException { PersonServiceps=newPersonService(); InputStreamxml=this.getClass().getClassLoader().getResourceAsStream("person.xml"); Listlst=ps.getPeople(xml); Assert.assertEquals("XY1",lst.get(0).getName()); } publicvoidtestSave()throwsException { PersonServiceps=newPersonService(); Listlst=newArrayList(); lst.add(newPerson("0001","XY0001",20)); lst.add(newPerson("0002","XY0002",20)); FilexmlFile=newFile(this.getContext().getFilesDir(),"xy.xml");//data/data/packagename/files OutputStreamos=newFileOutputStream(xmlFile); ps.saveDataToXML(os,lst); } } 本文参考自金旭亮老师的《.NET 4.0面向对象编程漫谈》有关代理的内容 本文转自IT徐胖子的专栏博客51CTO博客,原文链接http://blog.51cto.com/woshixy/1079595如需转载请自行联系原作者 woshixuye111

优秀的个人博客,低调大师

苹果iOS开发深入浅出Cocoa之类与对象

最近打算写一些ObjC中比较底层的东西,尤其是 runtime 相关的。苹果已经将 ObjC runtime 代码开源了,我们可以从:http://opensource.apple.com/source/objc4/objc4-493.9/runtime/浏览源代码,或点此下载源代码。 从哪里入手呢?那当然是最基本的类与对象。与C++相比,ObjC中的类与对象结构要简洁与一致得多(参考《深度探索C++对象模型》,你就知道C++中类与对象结构的复杂)。本文将详细讲解ObjC中类与对象的结构,下回将讲如何在 runtime 时操作类。 我们可以在/usr/include/objc/objc.h 和 runtime.h 中找到对 class 与 object 的定义: typedef struct objc_class *Class; typedef struct objc_object { Class isa; } *id; Class 是一个 objc_class 结构类型的指针;而 id(任意对象) 是一个 objc_object 结构类型的指针,其第一个成员是一个 objc_class 结构类型的指针。注意这里有一关键的引申解读:内存布局以一个 objc_class 指针为开始的所有东东都可以当做一个 object 来对待! 那 objc_class 又是怎样一个结构体呢?且看: struct objc_class { struct objc_class* isa; struct objc_class* super_class; const char* name; long version; long info; long instance_size; struct objc_ivar_list* ivars; struct objc_method_list** methodLists; struct objc_cache* cache; struct objc_protocol_list* protocols; } objc_class 结构体的各成员介绍如下: isa:是一个 objc_class 类型的指针,看到这里,想起我前面的引申解读了没?内存布局以一个 objc_class 指针为开始的所有东东都可以当做一个 object 来对待! 这就是说 objc_class 或者说类其实也可以当做一个 objc_object 对象来对待!对象是对象,类也是对象,是不是有点混淆?别急,ObjC发明(or 重用)了一个术语来区分这两种不同的对象:类对象(class object)与实例对象(instance object)。OK,名称混淆的问题解决,下面我将使用这两个术语来区分不同的对象,而使用“对象”这一术语来泛指所有的对象。ObjC还对类对象与实例对象中的 isa 所指向的类结构作了不同的命名:类对象中的 isa 指向类结构被称作 metaclass,metaclass 存储类的static类成员变量与static类成员方法(+开头的方法);实例对象中的 isa 指向类结构称作 class(普通的),class 结构存储类的普通成员变量与普通成员方法(-开头的方法)。 super_class:一看就明白,指向该类的父类呗!如果该类已经是最顶层的根类(如 NSObject 或 NSProxy),那么 super_class 就为 NULL。 好,先中断一下其他类结构成员的介绍,让我们厘清一下在继承层次中,子类,父类,根类(这些都是普通 class)以及其对应的 metaclass 的 isa 与 super_class 之间关系: 规则一:类的实例对象的 isa 指向该类;该类的 isa 指向该类的 metaclass; 规则二:类的 super_class 指向其父类,如果该类为根类则值为 NULL; 规则三:metaclass 的 isa 指向根 metaclass,如果该 metaclass 是根 metaclass 则指向自身; 规则四:metaclass 的 super_class 指向父 metaclass,如果该 metaclass 是根 metaclass 则指向该 metaclass 对应的类; 好吧,文字总是那么乏力,有图有真相! 那么 class 与 metaclass 有什么区别呢? class 是 instance object 的类类型。当我们向实例对象发送消息(实例方法)时,我们在该实例对象的 class 结构的 methodlists 中去查找响应的函数,如果没找到匹配的响应函数则在该 class 的父类中的 methodlists 去查找(查找链为上图的中间那一排)。如下面的代码中,向str 实例对象发送 lowercaseString 消息,会在 NSString 类结构的 methodlists 中去查找 lowercaseString 的响应函数。 NSString * str;[str lowercaseString]; metaclass 是 class object 的类类型。当我们向类对象发送消息(类方法)时,我们在该类对象的 metaclass 结构的 methodlists 中去查找响应的函数,如果没有找到匹配的响应函数则在该 metaclass 的父类中的 methodlists 去查找(查找链为上图的最右边那一排)。如下面的代码中,向 NSString 类对象发送 stringWithString 消息,会在 NSString 的 metaclass 类结构的 methodlists 中去查找 stringWithString 的响应函数。 [NSString stringWithString:@"str"]; 好,至此我们明白了类的结构层次,让我们接着看类结构中的其他成员。 name:一个 C 字符串,指示类的名称。我们可以在运行期,通过这个名称查找到该类(通过:id objc_getClass(const char *aClassName))或该类的 metaclass(id objc_getMetaClass(const char *aClassName)); version:类的版本信息,默认初始化为 0。我们可以在运行期对其进行修改(class_setVersion)或获取(class_getVersion)。 info:供运行期使用的一些位标识。有如下一些位掩码: CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含实例方法和变量; CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法; CLS_INITIALIZED (0x4L) 表示该类已经被运行期初始化了,这个标识位只被 objc_addClass 所设置; CLS_POSING (0x8L) 表示该类被 pose 成其他的类;(poseclass 在ObjC 2.0中被废弃了); CLS_MAPPED (0x10L) 为ObjC运行期所使用 CLS_FLUSH_CACHE (0x20L) 为ObjC运行期所使用 CLS_GROW_CACHE (0x40L) 为ObjC运行期所使用 CLS_NEED_BIND (0x80L) 为ObjC运行期所使用 CLS_METHOD_ARRAY (0x100L) 该标志位指示 methodlists 是指向一个 objc_method_list 还是一个包含 objc_method_list 指针的数组; instance_size:该类的实例变量大小(包括从父类继承下来的实例变量); ivars:指向 objc_ivar_list 的指针,存储每个实例变量的内存地址,如果该类没有任何实例变量则为 NULL; methodLists:与 info 的一些标志位有关,CLS_METHOD_ARRAY 标识位决定其指向的东西(是指向单个 objc_method_list还是一个 objc_method_list 指针数组),如果 info 设置了 CLS_CLASS 则 objc_method_list 存储实例方法,如果设置的是 CLS_META 则存储类方法; cache:指向 objc_cache 的指针,用来缓存最近使用的方法,以提高效率; protocols:指向 objc_protocol_list 的指针,存储该类声明要遵守的正式协议。 总结: ObjC 为每个类的定义生成两个 objc_class ,一个即普通的 class,另一个即 metaclass。我们可以在运行期创建这两个 objc_class 数据结构,然后使用 objc_addClass 动态地创建新的类定义。这个够动态够强大的吧?下回讲演示如何在运行期动态创建新类。 本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/782033,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS开发-Get请求,Post请求,同步请求和异步请求

标题中的Get和Post是请求的两种方式,同步和异步属于实现的方法,Get方式有同步和异步两种方法,Post同理也有两种。稍微有点Web知识的,对Get和Post应该不会陌生,常说的请求处理响应,基本上请求的是都是这两个哥们,Http最开始定义的与服务器交互的方式有八种,不过随着时间的进化,现在基本上使用的只剩下这两种,有兴趣的可以参考本人之前的博客Http协议中Get和Post的浅谈,iOS客户端需要和服务端打交道,Get和Post是跑不了的,本文中包含iOS代码和少量Java服务端代码,开始正题吧. Get和Post同步请求 Get和Post同步请求的时候最常见的是登录,输入各种密码才能看到的功能,必须是同步,异步在Web上局部刷新的时候用的比较多,比较耗时的时候执行异步请求,可以让客户先看到一部分功能,然后慢慢刷新,举个例子就是餐馆吃饭的时候点了十几个菜,给你先上一两个吃着,之后给别人上,剩下的慢慢上。大概就是这样的。弄了几个按钮先上图: 先贴下同步请求的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //设置URL路径 NSString *urlStr=[ NSString stringWithFormat:@ "http://localhost:8080/MyWeb/Book?username=%@&password=%@&type=get" ,@ "博客园" ,@ "keso" ]; urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; NSURL *url=[ NSURL URLWithString:urlStr]; //通过URL设置网络请求 NSURLRequest *request = [[ NSURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; NSError *error= nil ; //获取服务器数据 NSData *requestData= [ NSURLConnection sendSynchronousRequest:request returningResponse: nil error:&error]; if (error) { NSLog (@ "错误信息:%@" ,[error localizedDescription]); } else { NSString *result=[[ NSString alloc]initWithData:requestData encoding: NSUTF8StringEncoding ]; NSLog (@ "返回结果:%@" ,result); } 代码很多,需要解释一下: ①URL如果有中文无法传递,需要编码一下: 1 [urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; ②设置网路请求中的代码,有两个参数,最后一个设置请求的时间,这个不用说什么,重点说下缓存策略cachePolicy,系统中的定义如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 typedef NS_ENUM ( NSUInteger , NSURLRequestCachePolicy ) { NSURLRequestUseProtocolCachePolicy = 0, NSURLRequestReloadIgnoringLocalCacheData = 1, NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData , NSURLRequestReturnCacheDataElseLoad = 2, NSURLRequestReturnCacheDataDontLoad = 3, NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented }; NSURLRequestUseProtocolCachePolicy(基础策略),NSURLRequestReloadIgnoringLocalCacheData(忽略本地缓存); NSURLRequestReloadIgnoringLocalAndRemoteCacheData(无视任何缓存策略,无论是本地的还是远程的,总是从原地址重新下载); NSURLRequestReturnCacheDataElseLoad(首先使用缓存,如果没有本地缓存,才从原地址下载); NSURLRequestReturnCacheDataDontLoad(使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作); NSURLRequestReloadRevalidatingCacheData(如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载); Java服务端代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType( "text/html;charset=utf-8;" ); PrintWriter out = response.getWriter(); System.out.println(request.getParameter( "username" )); System.out.println(request.getParameter( "password" )); if (request.getParameter( "type" ) == null ) { out.print( "默认测试" ); } else { if (request.getParameter( "type" ).equals( "async" )) { out.print( "异步Get请求" ); } else { out.print( "Get请求" ); } } } 最终效果如下: Post请求的代码,基本跟Get类型,有注释,就不多解释了: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //设置URL NSURL *url=[ NSURL URLWithString:@ "http://localhost:8080/MyWeb/Book" ]; //创建请求 NSMutableURLRequest *request = [[ NSMutableURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; [request setHTTPMethod:@ "POST" ]; //设置请求方式为POST,默认为GET NSString *param= @ "Name=博客园&Address=http://www.cnblogs.com/xiaofeixiang&Type=post" ;//设置参数 NSData *data = [param dataUsingEncoding: NSUTF8StringEncoding ]; [request setHTTPBody:data]; //连接服务器 NSData *received = [ NSURLConnection sendSynchronousRequest:request returningResponse: nil error: nil ]; NSString *result= [[ NSString alloc]initWithData:received encoding: NSUTF8StringEncoding ]; NSLog (@ "%@" ,result); Java服务端代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding( "utf-8" ); response.setContentType( "text/html;charset=utf-8" ); PrintWriter out = response.getWriter(); System.out.println( "姓名:" + request.getParameter( "Name" )); System.out.println( "地址:" + request.getParameter( "Address" )); System.out.println( "类型:" + request.getParameter( "Type" )); if (request.getParameter( "Type" ).equals( "async" )) { out.print( "异步请求" ); } else { out.print( "Post请求" ); } } 效果如下: Get和Post异步请求 异步实现的时候需要实现协议NSURLConnectionDataDelegate,Get异步代码如下: 1 2 3 4 5 6 7 8 9 10 //设置URL路径 NSString *urlStr=[ NSString stringWithFormat:@ "http://localhost:8080/MyWeb/Book?username=%@&password=%s&type=async" ,@ "FlyElephant" , "keso" ]; urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; NSURL *url=[ NSURL URLWithString:urlStr]; //创建请求 NSURLRequest *request = [[ NSURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; //连接服务器 NSURLConnection *connection = [[ NSURLConnection alloc]initWithRequest:request delegate: self ]; 实现协议的连接过程的方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response{ NSHTTPURLResponse *res = ( NSHTTPURLResponse *)response; NSLog (@ "%@" ,[res allHeaderFields]); self .myResult = [ NSMutableData data]; } ////接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次 -( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data { [ self .myResult appendData:data]; } //数据传输完成之后执行方法 -( void )connectionDidFinishLoading:( NSURLConnection *)connection { NSString *receiveStr = [[ NSString alloc]initWithData: self .myResult encoding: NSUTF8StringEncoding ]; NSLog (@ "%@" ,receiveStr); } //网络请求时出现错误(断网,连接超时)执行方法 -( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error { NSLog (@ "%@" ,[error localizedDescription]); } 异步传输的过程数据需要拼接,所以这个时候需要设置一个属性接收数据: 1 @property (strong, nonatomic ) NSMutableData *myResult; 效果如下: Post异步传递代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //设置URL NSURL *url=[ NSURL URLWithString:@ "http://localhost:8080/MyWeb/Book" ]; //设置请求 NSMutableURLRequest *request = [[ NSMutableURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; [request setHTTPMethod:@ "POST" ]; //设置请求方式为POST,默认为GET NSString *param= @ "Name=keso&Address=http://www.cnblogs.com/xiaofeixiang&Type=async" ;//设置参数 NSData *data = [param dataUsingEncoding: NSUTF8StringEncoding ]; [request setHTTPBody:data]; //连接服务器 NSURLConnection *connection = [[ NSURLConnection alloc]initWithRequest:request delegate: self ]; 效果如下: 异步的请求比较简单,需要的方法都已经被封装好了,需要注意数据是动态拼接的,请求的代码都是在Java Servlet中实现的,Java项目中的目录如下: Book.java中代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.io.IOException; import java.io.PrintWriter; import java.net.URLDecoder; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Book */ @WebServlet ( "/Book" ) public class Book extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Book() { super (); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType( "text/html;charset=utf-8;" ); PrintWriter out = response.getWriter(); System.out.println(request.getParameter( "username" )); System.out.println(request.getParameter( "password" )); if (request.getParameter( "type" ) == null ) { out.print( "默认测试" ); } else { if (request.getParameter( "type" ).equals( "async" )) { out.print( "异步Get请求" ); } else { out.print( "Get请求" ); } } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding( "utf-8" ); response.setContentType( "text/html;charset=utf-8" ); PrintWriter out = response.getWriter(); System.out.println( "姓名:" + request.getParameter( "Name" )); System.out.println( "地址:" + request.getParameter( "Address" )); System.out.println( "类型:" + request.getParameter( "Type" )); if (request.getParameter( "Type" ).equals( "async" )) { out.print( "异步Post请求" ); } else { out.print( "Post请求" ); } } } Get和Post总结 ①同步请求一旦发送,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作(例如登录验证); ②异步请求不会阻塞主线程,会建立一个新的线程来操作,发出异步请求后,依然可以对UI进行操作,程序可以继续运行; ③Get请求,将参数直接写在访问路径上,容易被外界看到,安全性不高,地址最多255字节; ④Post请求,将参数放到body里面,安全性高,不易被捕获; 本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4306786.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

[Android学习笔记九] Android 开发中图片灰阶(黑白)显示

灰阶显示图片的典型应用就是用户头像,如用户在线头像显示彩色(原图),不在线显示灰色(黑白图)。总结一点就是更加一张原始图片来通过颜色的过滤处理计算得到不同显示效果的图片。这方法的API主要位于:android. 使用上文中提到的“三种算法转换彩色灰阶”一文中提到的灰阶计算方法产生的黑白图片显示效果如下图: 说明:通过Use Matrix是使用Android的ColorMatrix和ColorFilter实现,其中设置ColorMatrix的setSaturation(float sat)饱和度设置为0时颜色过滤之后显示灰阶,android.graphics.ColorMatrix的内部实现和具体RGB颜色权重值近似等于图中BT709中的权重。 代码示例(依赖此文中附加的灰阶计算方法封装类) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 @Override protected void onCreate(BundlesavedInstanceState){ super .onCreate(savedInstanceState); setContentView(R.layout.activity_grayscale); ButterKnife.bind( this ); BitmapDrawablebd=(BitmapDrawable)Original_ImageView.getDrawable(); Bitmapbitmap=bd.getBitmap(); Log.d(TAG, "w=" +bitmap.getWidth()+ ",h=" +bitmap.getHeight()+ ",c=" +bitmap.getConfig().toString()); //0BT709 Bitmapmatrix=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888); Canvascanvas= new Canvas(matrix); Paintpaint= new Paint(); ColorMatrixcolorMatrix= new ColorMatrix(); //传入一个大于1的数字将增加饱和度,而传入一个0~1之间的数字会减少饱和度。0值将产生一幅灰度图像 //AndroidColorMatrix默认的灰阶计算采用下面的BT709标准 colorMatrix.setSaturation(0f); ColorMatrixColorFiltercolorMatrixColorFilter= new ColorMatrixColorFilter(colorMatrix); paint.setColorFilter(colorMatrixColorFilter); canvas.drawBitmap(bitmap,0f,0f,paint); Matrix_ImageView.setImageBitmap(matrix); //原始图片 Bitmapsunflower=XUtils.BitmapUtil.decodeMutableBitmapFromResourceId( this ,R.drawable.sunflower); //1 Bitmaplightness=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.Lightness); Lightness_ImageView.setImageBitmap(lightness); //2 Bitmapaverage=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.Average); Average_ImageView.setImageBitmap(average); //3 Bitmapluminosity=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.Luminosity); Luminosity_ImageView.setImageBitmap(luminosity); //4 Bitmapbt709=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.BT709); BT709_ImageView.setImageBitmap(bt709); //5 Bitmaprmy=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.RMY); RMY_ImageView.setImageBitmap(rmy); //6 Bitmapy=grayScale(sunflower,XUtils.GrayScaleUtil.GrayScale.Y); Y_ImageView.setImageBitmap(y); } public BitmapgrayScale( final Bitmapbitmap,XUtils.GrayScaleUtil.GrayScalegrayScale){ if ( null ==bitmap|| null ==grayScale){ return null ; } Bitmaprs=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888); Canvascanvas= new Canvas(rs); Paintpaint= new Paint(); for ( int x= 0 ,w=bitmap.getWidth();x<w;x++){ for ( int y= 0 ,h=bitmap.getHeight();y<h;y++){ int c=bitmap.getPixel(x,y); int a=Color.alpha(c); int r=Color.red(c); int g=Color.red(c); int b=Color.blue(c); int gc=grayScale.grayScale(r,g,b); paint.setColor(Color.argb(a,gc,gc,gc)); canvas.drawPoint(x,y,paint); } } return rs; } 关于ColorMatrix的介绍参见Android document : 本地:${SDK}/docs/reference/android/graphics/ColorMatrix.html 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1719008,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS访问通讯录开发-读取联系人信息

读取通信录中的联系人一般的过程是先查找联系人记录,然后再访问记录的属性,属性又可以分为单值属性和多值属性。通过下面例子介绍联系人的查询,以及单值属性和多值属性的访问,还有读取联系人中的图片数据。 本案例是从iOS设备上读取通讯录中的联系人,并将其显示在一个表视图中,可以进行查询,点击联系人进入详细信息画面。访问通讯录的应用必须要做的两件事情: 1、添加AddressBook和AddressBookUI框架 为工程添加AddressBook.framework和AddressBookUI.framework 2、引入头文件 在需要访问通讯录类的头文件中引入下面头文件: #import <AddressBook/AddressBook.h> #import <AddressBookUI/AddressBookUI.h> 查询联系人记录 在从通信录数据库查询联系人数据是无法使用SQL语句,只能通过ABAddressBookCopyArrayOfAllPeople和ABAddressBookCopyPeopleWithName函数获得,它们的定义如下: 1 2 3 4 5 6 7 CFArrayRef ABAddressBookCopyArrayOfAllPeople ( ABAddressBookRef addressBook ); CFArrayRef ABAddressBookCopyPeopleWithName ( ABAddressBookRef addressBook, CFStringRef name ); ABAddressBookCopyArrayOfAllPeople函数是查询所有的联系人数据。ABAddressBookCopyPeopleWithName函数是通过人名查询通讯录中的联系人,其中的name参数就是查询的前缀关键字。两个函数中都有addressBook参数,它是我们要查询的通讯录对象,其创建使用ABAddressBookCreateWithOptions函数(在iOS6之前是ABAddressBookCreate函数),它的定义: 1 2 3 4 ABAddressBookRef ABAddressBookCreateWithOptions ( CFDictionaryRef options, CFErrorRef* error ); options参数是保留参数,目前没有采用,使用时候可以传递NULL值。error是错误对象,包含错误信息。 下面是我们代码中有关系查询的部分,先看一下ViewController.h: 1 2 3 4 5 6 7 8 # import <UIKit/UIKit.h> # import <AddressBook/AddressBook.h> # import ”DetailViewController.h” @ interface ViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate> @property (nonatomic, strong) NSArray *listContacts; - ( void )filterContentForSearchText:(NSString*)searchText; @end 属性listContacts是装载联系人记录数组集合,filterContentForSearchText:方法是用来过滤联系人信息的方法,也就是查询方法。 ViewController.m中的viewDidLoad方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 - ( void )viewDidLoad { [super viewDidLoad]; CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); ① ABAddressBookRequestAccessWithCompletion(addressBook, ^( bool granted, CFErrorRef error) { ② if (granted) { //查询所有 [self filterContentForSearchText:@ "" ]; ③ } }); CFRelease(addressBook); ④ } 在viewDidLoad方法中首先在第①行代码处使用ABAddressBookCreateWithOptions函数创建addressBook对象,然后在第②行又调用了函数ABAddressBookRequestAccessWithCompletion,这个函数用于向用户请求访问通讯录数据库,如果是第一次访问,则会弹出一个用户授权对话框,如果用户授权可以访问则会调用下面的代码块。 1 2 3 4 ^(bool granted, CFErrorRef error) { if (granted) { } }); 由于请求和代码块的回调都是异步的,你会发现表视图画面先出现,然后过一会儿才有查询出来的结果。在iOS6之后这个请求过程必须有的,否则无法访问通讯录数据库。 ViewController.m中的filterContentForSearchText:查询方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - ( void )filterContentForSearchText:(NSString*)searchText { //如果没有授权则退出 if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) { return ; } CFErrorRef error = NULL; ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); if ([searchText length]== 0 ) { //查询所有 self.listContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); } else { //条件查询 CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText); self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); CFRelease(cfSearchText); } [self.tableView reloadData]; CFRelease(addressBook); } 在该方法中实现查询,ABAddressBookGetAuthorizationStatus()函数返回应用的授权状态,其中kABAuthorizationStatusAuthorized常量代表用户已经授权,在没有授权情况下该方法不进行任何处理。ABAddressBookCopyArrayOfAllPeople函数是查询所有数据,ABAddressBookCopyPeopleWithName函数是根据条件查询,返回值是CFArrayRef类型,不能直接赋值给listContacts(NSArray*类型)属性,处理方式一般如下两种: self.listContacts = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook) ; 或 self.listContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); (__bridge NSArray *)方式不会转让对象所有权,只是简单强制转化。CFBridgingRelease函数实现的是Core Foundation类型到Foundation类型转化并把对象所有权转让ARC(自动管理引用计数),因此不需要释放属性listContacts对应的成员变量。类似还有CFBridgingRetain函数,实现的是Foundation类型到Core Foundation类型转化, 并把对象所有权转让调用者,因此需要释放这个对象,代码如下: CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText); self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); CFRelease(cfSearchText); 1 2 3 CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText); self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); CFRelease(cfSearchText); 最后在第④行调用CFRelease(addressBook)函数释放addressBook对象,Core Foundation框架中的数据类型内存管理是不受ARC管理的,但是与Foundation框架的MRC管理类似,需要手动释放,CFRelease函数就是相当于Foundation框架中的release(或autorelease)方法。 ViewController.m中的SearchBar查询相关方法: #pragma mark –UISearchBarDelegate 协议方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - ( void )searchBarCancelButtonClicked:(UISearchBar *)searchBar { //查询所有 [self filterContentForSearchText:@ "" ]; } #pragma mark - UISearchDisplayController Delegate Methods //当文本内容发生改变时候,向表视图数据源发出重新加载消息 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { [self filterContentForSearchText:searchString]; //YES情况下表视图可以重新加载 return YES; } 读取单值属性 在一条联系人记录中,有很多属性,这些属性有单值属性和多值属性,单值属性是只有一个值的属性,如:姓氏、名字等,它们是由下面常量定义的: kABPersonFirstNameProperty,名字 kABPersonLastNameProperty,姓氏 kABPersonMiddleNameProperty,中间名 kABPersonPrefixProperty,前缀 kABPersonSuffixProperty,后缀 kABPersonNicknameProperty,昵称 kABPersonFirstNamePhoneticProperty,名字汉语拼音或音标 kABPersonLastNamePhoneticProperty,姓氏汉语拼音或音标 q kABPersonMiddleNamePhoneticProperty,中间名汉语拼音或音标 kABPersonOrganizationProperty,组织名 kABPersonJobTitleProperty,头衔 kABPersonDepartmentProperty,部门 kABPersonNoteProperty,备注 读取记录属性函数是ABRecordCopyValue,ABRecordCopyValue函数的定义如下: CFTypeRef ABRecordCopyValue ( ABRecordRef record, ABPropertyID property ); ABRecordRef参数是记录对象,ABPropertyID是属性ID,就是上面的常量kABPersonFirstNameProperty等。返回值类型是CFTypeRef,它是Core Foundation类型的“泛型”,可以代表任何的Core Foundation类型。 ViewController.m中的tableView:cellForRowAtIndexPath:方法,主要实现了访问单值属性: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @”Cell”; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]); ① NSString *firstName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty)); ② firstName = firstName != nil?firstName:@”"; NSString *lastName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonLastNameProperty)); ③ lastName = lastName != nil?lastName:@”"; cell.textLabel.text = [NSString stringWithFormat:@ "%@ %@" ,firstName,lastName]; CFRelease(thisPerson); return cell; } 第①行ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]])语句是从NSArray*集合中取出一个元素,并且转化为Core Foundation类型的ABRecordRef类型。CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty))语句是将名字属性取出来,转化为NSString*类型。最后CFRelease(thisPerson)是释放ABRecordRef对象。 此外,为了把选中的联系人传递给详细画面,我们需要获得选中记录的ID,然后把ID传递到详细画面,这个过程处理是在ViewController.m中的 prepareForSegue:方法完成的: 1 2 3 4 5 6 7 8 9 10 11 12 - ( void )prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@”showDetail”]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]); DetailViewController *detailViewController = [segue destinationViewController]; ABRecordID personID = ABRecordGetRecordID(thisPerson); ① NSNumber *personIDAsNumber = [NSNumber numberWithInt:personID]; ② detailViewController.personIDAsNumber = personIDAsNumber; ③ CFRelease(thisPerson); ④ } } 其中第①行代码调用函数ABRecordGetRecordID是获取选中记录的ID,其中ID为ABRecordID类型。为了传递这个ID给DetailViewController视图控制器,DetailViewController视图控制器定义了personIDAsNumber属性,在第③行将ID给personIDAsNumber属性。DetailViewController.h代码如下: #import <UIKit/UIKit.h> #import <AddressBook/AddressBook.h> @interface DetailViewController : UITableViewController @property (weak, nonatomic) IBOutlet UIImageView *imageView; @property (weak, nonatomic) IBOutlet UILabel *lblName; @property (weak, nonatomic) IBOutlet UILabel *lblMobile; @property (weak, nonatomic) IBOutlet UILabel *lblIPhone; @property (weak, nonatomic) IBOutlet UILabel *lblWorkEmail; @property (weak, nonatomic) IBOutlet UILabel *lblHomeEmail; @property (strong, nonatomic) NSNumber* personIDAsNumber; @end personIDAsNumber属性为NSNumber*类型。 读取多值属性 多值属性是包含多个值的集合类型,如:电话号码、Email、URL等,它们主要是由下面常量定义的: kABPersonPhoneProperty,电话号码属性,kABMultiStringPropertyType类型多值属性; kABPersonEmailProperty,Email属性,kABMultiStringPropertyType类型多值属性; kABPersonURLProperty,URL属性,kABMultiStringPropertyType类型多值属性; kABPersonRelatedNamesProperty,亲属关系人属性,kABMultiStringPropertyType类型多值属性; kABPersonAddressProperty,地址属性,kABMultiDictionaryPropertyType类型多值属性; kABPersonInstantMessageProperty,即时聊天属性,kABMultiDictionaryPropertyType类型多值属性; kABPersonSocialProfileProperty,社交账号属性,kABMultiDictionaryPropertyType类型多值属性; 在多值属性中包含了label(标签)、value(值)和ID等部分,其中标签和值都是可以重复的,而ID是不能重复的 多值属性访问方式与单值属性访问类似都使用ABRecordCopyValue函数。不同的是多值属性访问返回值是ABMultiValueRef,然后要使用ABMultiValueCopyArrayOfAllValues函数从ABMultiValueRef对象中获取数组CFArrayRef集合。ABMultiValueCopyArrayOfAllValues函数的定义如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CFArrayRef ABMultiValueCopyArrayOfAllValues ( ABMultiValueRef multiValue ); ABMultiValueCopyLabelAtIndex函数可以从ABMultiValueRef对象中返回标签,其定义如下: CFStringRef ABMultiValueCopyLabelAtIndex ( ABMultiValueRef multiValue, CFIndex index ); 参数multiValue是ABMultiValueRef对象,index是查找标签的索引。 ABMultiValueGetIdentifierAtIndex函数可以从ABMultiValueRef对象中返回ID,其定义如下: ABMultiValueIdentifier ABMultiValueGetIdentifierAtIndex ( ABMultiValueRef multiValue, CFIndex index ); 在DetailViewController.m文件viewDidLoad方法中取得Email多值属性,其代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ABMultiValueRef emailsProperty = ABRecordCopyValue(person, kABPersonEmailProperty); NSArray* emailsArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(emailsProperty)); for ( int index = 0 ; index< [emailsArray count]; index++){ NSString *email = [emailsArray objectAtIndex:index]; NSString *emailLabel = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emailsProperty, index)); if ([emailLabel isEqualToString:(NSString*)kABWorkLabel]) { [self.lblWorkEmail setText:email]; } else if ([emailLabel isEqualToString:(NSString*)kABHomeLabel]) { [self.lblHomeEmail setText:email]; } else { NSLog(@”%@: %@”, @”其它Email”, email); } } CFRelease(emailsProperty); 其中ABMultiValueCopyArrayOfAllValues(emailsProperty))语句是从emailsProperty属性中取出数组集合。kABWorkLabel和kABHomeLabel都是Email多值属性的标签。kABWorkLabel是工作Email标签和kABHomeLabel是家庭Email标签,另外还有kABOtherLabel,它是Email标签。最后emailsProperty需要释放。 DetailViewController.m中的viewDidLoad方法中取得电话号码多值属性代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty); NSArray* phoneNumberArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(phoneNumberProperty)); for ( int index = 0 ; index< [phoneNumberArray count]; index++){ NSString *phoneNumber = [phoneNumberArray objectAtIndex:index]; NSString *phoneNumberLabel = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phoneNumberProperty, index)); if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneMobileLabel]) { [self.lblMobile setText:phoneNumber]; } else if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]) { [self.lblIPhone setText:phoneNumber]; } else { NSLog(@”%@: %@”, @”其它电话”, phoneNumber); } } CFRelease(phoneNumberProperty); kABPersonPhoneMobileLabel和kABPersonPhoneIPhoneLabel都是电话号码属性的标签。kABPersonPhoneMobileLabel是移动电话号码标签,kABPersonPhoneIPhoneLabel是iPhone电话号码标签。此外还有: kABPersonPhoneMainLabel,主要电话号码标签; kABPersonPhoneHomeFAXLabel,家庭传真电话号码标签; kABPersonPhoneWorkFAXLabel,工作传真电话号码标签; kABPersonPhonePagerLabel,寻呼机号码标签。 11.2.4 读取图片属性 通讯录中的联系人可以有一个图片,读取联系人图片的相关函数有ABPersonCopyImageData和ABPersonHasImageData等。ABPersonCopyImageData可以读取联系人图片函数,它的定义如下: CFDataRef ABPersonCopyImageData ( ABRecordRef person ); 它的返回类型是CFDataRef,与之对应的Foundation框架类型是NSData*。ABPersonHasImageData函数用于判断联系人是否有图片,它的定义如下: 1 2 3 bool ABPersonHasImageData ( ABRecordRef person ); DetailViewController.m中的viewDidLoad方法中取得联系人图片代码如下: if (ABPersonHasImageData(person)) { 1 2 3 4 5 NSData *photoData = CFBridgingRelease(ABPersonCopyImageData(person)); if (photoData){ [self.imageView setImage:[UIImage imageWithData:photoData]]; } } ABPersonCopyImageData取出的是CFDataRef类型,将其转化为NSData*,再使用UIImage的构造方法imageWithData:构建UIImage对象,然后再把UIImage对象赋值给imageView图片控件。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1238527,如需转载请自行联系原作者

优秀的个人博客,低调大师

Centos7下安装eclipse进行C/C++开发

1)下载eclipse Eclipse下载网址:https://www.eclipse.org/downloads/ 注意选择的时候选择Eclipse IDE for C/C++ Developers 2)下载cdt cdt下载网址:www.eclipse.org/cdt/ 3)安装 进入要“安装软件”的目录然后,解压eclipse-jee-kepler-RC3-Linux-gtk.tar.gz压缩包命令是 tar –zxvf eclipse-jee-kepler-RC3-linux-gtk.tar.gz得到:eclipse文件夹 4)安装cdt 在终端输入:unzip cdt-master-8.1.2.zip –d cdt,可以把cdt-master-8.1.2.zip解压并且它的内容存放在cdt文件夹下。再输入:cp –r cdt/plugins/ eclipse/,则将cdt下plugins的内容拷贝到eclipse下plugins文件夹。最后,输入cp –r cdt/features/ eclipse/,则将cdt下features的内容拷贝到eclipse下features文件夹。 到现在,安装已经完成。 5)测试Eclipse是否可以工作 直接打开eclipse文件下的eclipse文件,运行弹出窗口,测试成功,否则,不成功,请验证是否安装JDK。按照本章节操作,cetos系统必须提前安装好JDK之类的,否则会出错。 6)eclipse cdt运行c程序报错“launch failed,binary not found” 在CDT中每一次新项目建成后,系统一般默认会进行第一次的构建,也就是自动生成可执行文件。可是事实我们在刚新建的项目甚至还没有源码文 件,所以当然不 会生成可执行的文件了。当我们新建了一个源码文件时,点击执行按钮,就会弹出所说的”launch failed.Binary not found “提示说明(找不到可运行的二进制文件)。 解决办法:窗口左面的项目文件夹上右键鼠标,在弹出的菜单中选择Build Configurations —>Build selected,选择其中的debug或者release进行构建。 7)在应用菜单中添加菜单项—–把eclipse添加到应用菜单中 gnome桌面的所有菜单项都存储如下位置: /usr/share/applications/ 新建一个菜单项,直接在该目录下新建一个后缀名为.desktop的文件即可。 vim /usr/share/applications/c-eclipse.desktop 文件内容如下: [Desktop Entry] Version=1.0 Name=C-Eclipse Icon=/opt/eclipse/icon.xpm Exec=/opt/eclipse/eclipse Terminal=false Type=Application StartupNotify=true Categories=Application;Development;IDE 三、参考文章 1.http://www.centoscn.com/image-text/install/2016/0529/7296.html 2.http://www.360kb.com/kb/2_140.html 3.http://blog.csdn.net/u011345885/article/details/51871435 4.http://www.centoscn.com/CentOS/config/2015/1106/6391.html

优秀的个人博客,低调大师

Android GIS开发系列-- 入门季(12) 显示载天地图

在项目中可以经常需要动态加载一些图层,像投影地图服务、投影地图服务器。其实网上有大量这样的服务,比如天地图官网, 。 随便点开一个服务,里面有相关的信息。那如何加载这样图层服务呢。 一、首先感谢这篇博文ArcGIS读取天地图出现错位的情况,这篇文章的下载链接也有许多有用的资料。加载天地图用到一个关键的自定义类TianDiTuLayer View Code 另外还有三个类,TianDiTuLayerInfo、LayerInfoFactory、TianDiTuLayerTypes这里就不贴代码了。资料下载。 二、我们修改一下代码 1.常量类TDTConstant: View Code 2.TianDiTuLayer,代码如下 : View Code 3.TianDiTuInfo实体类: View Code 4.Activity代码: View Code 调用的地图服务相关信息 效果图: 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/7751990.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android GIS开发系列-- 入门季(9) 定位当前的位置

利用MapView定位当前的位置 这里要用到Arcgis中的LocationDisplayManager这个类,由于比较简单。直接上代码: LocationDisplayManager locationDisplayManager = mMapView.getLocationDisplayManager();//获取定位类 locationDisplayManager.setShowLocation(true); locationDisplayManager.setAutoPanMode(LocationDisplayManager.AutoPanMode.LOCATION);//设置模式 locationDisplayManager.setShowPings(true); locationDisplayManager.start();//开始定位 由于是定位,在AndroidManifest文件中,要添加以下权限: <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 另外如果我们想获取定位点的位置,调用代码:Point point = locationDisplayManager.getPoint();即可获取。 没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。 本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/7751967.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

某android平板项目开发笔记---计划任务备份

前言: 很久,都没更新过这个系列了…因为,除了图表以外,然后就是数据库了,调试了一个多星期的Ormlite数据库,在最新版本中(orm 4.3.3)发现了几个比较严重的bug(例如,查找id的时候无法使用Long类型),不过,还好,ormlite社区还算活跃,bug,已经在预览中修复了.关于Ormlite数据库的话,园子里面已经有了写得很不错的教程了,我就不重复他们的劳动了.然后,数据库搞定了,就是写业务了,有这么一个业务,就是,要求,在某个时间点,对插入的数据进行后台更新,然后,就涉及到了使用计划任务这么一块知识,觉得有必要做下笔记,这块,以后应该也能用到 业务说明: 在某时某刻进行数据库的备份. 相关知识: 1,时间操作 (1) 熟悉使用Calendar 1,作为定时任务,我们需要一个具体的定时时间,以前,我是用Date 类取毫秒数,然后进行计数的操作 1.1例如 //以下为以前的某项目算相隔天数的演示代码 String startDate = mDateStart.getText().toString(); String endDate = year + "-" + (month + 1) + "-" + day; Log.d("soap", startDate + "---" + endDate); DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); // long day=(startC.getTime()-endC.getTime())/(24*60*60*1000); try { Date start = df.parse(startDate); Date end = df.parse(endDate); Long d = (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000); Log.d("soap", "相隔天数" + d); if (d &gt; 60) { return false; } else { return true; } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } 以前这样写,感觉挺傻的,希望大家不要学习了,这次的业务需求,如果,是以前的话,我会一个创建具体时间字符串,然后用SimpleDateFormat,获取毫秒数,这样个人感觉,很不直观,也麻烦,也不方便国际化,我们用Calendar做就非常简单了. 1.2 定时23:00 执行备份操作 竟然是定时任务,我们就要熟悉一个android的一个用于做定时任务的类 AlarmManager 各位,先去看一下官方文档,在接着看下去吧… 这个类是的初始化是必须要用Context.getSystemService(Context.ALARM_SERVICE). 以下为定时代码块 //初始化定时类 AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); //设置定时时间,1分钟后执行 Calendar c = Calendar.getInstance(); c.add(Calendar.MINUTE, 1); //设置时间到了执行的services Intent intent = new Intent(); //创建一个servcies intent.setClass(this, UpdateStatics.class); PendingIntent pi = PendingIntent.getService(this, 0, intent, 0); //设置定时 //需要android.permission.SET_TIME 权限 //第一个参数为定时类型(一共有四种,具体参见官方文档),第二个参数为设置的定时时间为long类型,第三个为执行的目标 am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); 以上代码就会在,1分钟后,系统执行UpdateStatics 类. 如果,我们要设置具体的时间,只要具体设置Calendar的对象即可,例如23:00分执行 c.set(Calendar.HOUR_OF_DAY, 23); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); 总结: 使用Calendar类操作时间,和进行时间计算,设置,是十分方便的事情, 2,备份操作 1, 建一个接口类用于,监听操作. public interface CompletionListener { void onBackupComplete(); void onRestoreComplete(); void onError(int errorCode); } 2,创建一个异步备份的类 public class BackupTask extends AsyncTask<String, Void, Integer> implements CompletionListener{ //定义常量 public static final int BACKUP_SUCCESS =1; public static final int RESTORE_SUCCESS = 2; public static final int BACKUP_ERROR = 3; public static final int RESTORE_NOFLEERROR = 4; public static final String COMMAND_BACKUP = "backupDatabase"; public static final String COMMAND_RESTORE = "restroeDatabase"; private Context mContext; public BackupTask(Context context){ this.mContext = context; } @Override protected Integer doInBackground(String... params) { //1,获得数据库路径 File dbFile = mContext.getDatabasePath("xxx.db"); //2,创建保存的数据库的路径 File exportDir = new File(Environment.getExternalStorageDirectory(),"shopBackup"); if(!exportDir.exists()){ exportDir.mkdirs(); } File backup = new File(exportDir, dbFile.getName()); //3,检查操作 String command = params[0]; if(command.equals(COMMAND_BACKUP)){ //复制文件 try { backup.createNewFile(); fileCopy(dbFile, backup); return BACKUP_SUCCESS; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return BACKUP_ERROR; } }else{ return BACKUP_ERROR; } } private void fileCopy(File source, File dest) throws IOException { FileChannel inChannel = new FileInputStream(source).getChannel(); FileChannel outChannel = new FileOutputStream(dest).getChannel(); // FileInputStream fis = new FileInputStream(dbFile); // FileOutputStream fos = new FileOutputStream(backup); // byte buffer[] = new byte[4 * 1024]; // while(fis.read(buffer) != -1){ // fos.write(buffer); // } // fos.flush(); // long size = inChannel.size(); try { inChannel.transferTo(0, inChannel.size(), outChannel); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(inChannel != null){ inChannel.close(); } if(outChannel != null){ outChannel.close(); } } } @Override protected void onPostExecute(Integer result) { // TODO Auto-generated method stub super.onPostExecute(result); switch (result) { case BACKUP_SUCCESS: onBackupComplete(); break; default: break; } } @Override public void onBackupComplete() { Log.d("backup", "ok"); } @Override public void onRestoreComplete() { // TODO Auto-generated method stub } @Override public void onError(int errorCode) { // TODO Auto-generated method stub } } 记得,设置好权限: android.permission.WRITE_EXTERNAL_STORAGE AsyncTask<Params,Progress,Result> 这个类的用法,官方文档已经解释的很详细了,这里也不做重复解释. 关于:fileCopy(File source, File dest) 这个方法,我这里改用了Nio 的方式进行操作.用注释注释的代码是一般的方式,这个两者有什么区别呢? 文档 java.nio.channels 类 FileChannel transferTo 里面有这么一句话 与从此通道读取并将内容写入目标通道的简单循环语句相比,此方法可能高效得多。很多操作系统可将字节直接从文件系统缓存传输到目标通道,而无需实际复制各字节。 看到这句话我就使用了这个方法了,然后,为了搞清楚实现的方式,我查看了一下transferTo 的源码只是一个抽象方法,然后,在的FileInputSteam里面找的了channel 的实现方法,不过可惜的,具体的实现代码,我的源码包没有. 然后我顺便比较了java 和 android java 对于获取,channel的区别 java jdk_1.6_u30 默认的fileChannel是用sun包进行实现,然后,关于实现的部分,应该要下个sun包的源码了吧,因为,没找的,就贴不出来了. public FileChannel getChannel() { synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, true, false, this); /* * Increment fd's use count. Invoking the channel's close() * method will result in decrementing the use count set for * the channel. */ fd.incrementAndGetUseCount(); } return channel; } android java getChannel的代码部分 public FileChannel getChannel() { // BEGIN android-changed synchronized(this) { if (channel == null) { channel = FileChannelFactory.getFileChannel(this, fd.descriptor, IFileSystem.O_RDONLY); } return channel; } // END android-changed } android java同样,我的源码包到实现filechannel 部分的代码就没了,对于获取filechannel ,google 是重写了sun那部分的代码了.至于两者的区别,我就不清楚了.有知道的朋友,望告知

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册