首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

ios开发学习--动画(Animation)效果源码分享

FTUtils 介绍: 实现各种各样的图形、动画效果。例子中展现的是各种各样视图出现和消失的例子,例如视图的淡入淡出、飞进飞出等等。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=26&fromuid=15Snow Fall 介绍: 实现落雪的动画效果。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=27Graphics Animation 介绍: 实现各种各样的图形、动画效果。例如图形变换、平移、渐变、缩放、旋转等等。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=28Campfire 介绍: 实现火焰动画效果。其实作者是利用多张火焰图片,做成一个image sequence,然后播放这个sequence,从而产生动态的火焰效果。老实说,这不是一个很好的实现方法,仅仅比嵌入一段视频好一点,还不如直接加载一副GIF动画图片。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=29Core Animation Demos 介绍: 实现各种各样的图形、动画效果。例如图形变换、平移、渐变、缩放、旋转、仪表盘、电子书翻页等等。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=31&fromuid=15Animation Showcase 介绍: 实现各种各样的图形、动画效果。例如图形变换、平移、渐变、缩放、旋转、烟雾等等。 http://ios.itmdc.com/forum.php?mod=viewthread&tid=30 本文转自qianqianlianmeng博客园博客,原文链接:http://www.cnblogs.com/aimeng/archive/2012/12/05/2803161.html ,如需转载请自行联系原作者

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

Storm概念学习系列之Topology拓扑

Hadoop 上运行的是 MapReduce 作业,而在Storm 上运行的是拓扑 Topology,这两者之间是非常不同的。一个关键的区别是:一个MapReduce 作业最终会结束,而一个 Topology 拓扑会永远运行(除非手动杀掉)。 Topology拓扑 从字面上解释Topology,就是网络拓扑,是指用传输介质互连各种设备的物理布局,是构成网络的成员间特定的物理的(即真实的),或者逻辑的,即虚拟的排列方式。拓扑是一种不考虑物体的大小、形状等物理属性,而只使用点或者线描述多个物体实际位置与关系的抽象表示方法。拓扑不关心事物的细节,也不在乎相互的比例关系,只是以图的形式表示一定范围内多个物体之间的相互关系。从Storm角度考虑,它不是网络拓扑,但是又类似于网络拓扑的结构,所以取名Topology。 那么Storm的Topology指的是类似于网络拓扑图的一种虚拟结构。Storm的拓扑Topology类似于MapReduce任务,一个关键的区别是MapReduce任务运行一段时间后最终会完成,而Storm拓扑一直运行(直到杀掉它)。一个拓扑是由Spout和Bolt组成的图,Spout和Bolt之间通过流分组连接起来。图1形象地描述了Topology中的Spout和Bolt之间的关系。 图1 Spout和Bolt的关系图 通过对图1的理解可以看出,Topology是由Spout、Bolt、数据载体Tuple等构成的一定规则的网络拓扑图。Storm提供了TopologyBuilder类来创建Topology。打个比方,TopologyBuilder是Topology的骨架,Spout、Bolt是Topology的肉和血液。TopologyBuilder类的主要方法如图2所示。 图 2 TopologyBuilder类的主要方法 TopologyBuilder实际上是封装了Topology的Thrift接口,也就是说Topology实际上是通过Thrift定义的一个结构,TopologyBuilder将这个对象建立起来,然后Nimbus实际上运行一个Thrift服务器,用于接收用户提交的结构。由于采用Thrift实现,所以用户可以用其他语言建立Topology,这样就提供了比较方便的多语言操作支持。 Topology实例 下面从一个简单的例子开始介绍Topology的构建和定义,通过此案例能够基本理解Storm,并且能够构建一个简单的Topology。本实例使用Topology来统计一个句子中单词出现的频率。下面详细介绍如何设计和运行Topology,以及一些注意事项。 1. 设计Topology结构 在编写代码之前,首先要设计Topology。在理清数据处理逻辑之后,创建Topology就非常简单了。统计单词词频的Topology的大致结构如图3所示。可以将Topology分成3个部分:一是数据源KafkaSpout,负责发送语句;二是数据处理者SplitSentenceBolt,负责切分语句;三是数据再处理者WordCountBolt,负责累加单词的频率。 图 3 Topology的结构 2. 设计数据流 设计的Topology是从KafkaSpout中读取句子,并把句子划分成单词,然后汇总每个单词出现的次数,一个Bolt负责获取句子后划分成单词,一个Bolt分别对应计算每一个单词出现的次数,然后Tuple在Spout和Bolt之间传递,如图3-15所示。 图4 Topology内部数据流图 3. 代码实现 (1)构建Maven环境 为了开发Topology,需要把Storm相关的JAR包添加到CLASSPATH中,要么手动添加所有相关的JAR包,要么使用Maven来管理所有的依赖。Storm的JAR包发布在Clojars(一个Maven库),如果使用Maven,需要把下面的配置代码添加在项目的pom.xml中。 <repository> <id>clojars.org</id> <url>http:// clojars.org/repo</url> </repository> <dependency> <groupId>storm</groupId> <artifactId>storm</artifactId> <version>0.8.2</version> <scope>test</scope> </dependency> (2)定义Topology 定义Topology的内部逻辑,代码如下: SpoutConf?ig kafkaConf?ig = new SpoutConf?ig(brokerHosts, "storm-sentence", "", "storm"); kafkaConf?ig.scheme = new SchemeAsMultiScheme(new StringScheme()); TopologyBuilder builder = new TopologyBuilder(); builder.setSpout(1,new KafkaSpout(kafkaConf?ig), 10);// id, spout, parallelism_hint builder.setBolt(2, new SplitSentence(), 10) .shuffleGrouping(1); builder.setBolt(3, new WordCount(), 20) .f?ieldsGrouping(2, new Fields("word")); 声明的Topology的Spout是从Kafka中读取句子,Spout用setSpout方法插入一个独特的ID到Topology中。Topology中的每个节点必须给予一个ID,ID是由其他Bolt用于订阅该节点的输出流,KafkaSpout在Topology中的ID为1。 setBolt用于在Topology中插入Bolt。在Topology中定义的第一个Bolt是切割句子的Bolt,该Bolt(即SplitSentence)将句子流转成单词流;setBolt的最后一个参数是Bolt的并行量,因为SplitSentence是10个并发,所以在Storm集群中有10个线程并行执行。当Topology遇到性能瓶颈时,可以通过增加Bolt并行数量来解决。setBolt方法返回一个对象,用来定义Bolt的输入。例如,SplitSentence约定使用组件ID为1的输出流,1是指已经定义的KafkaSpout。SplitSentence会消耗KafkaSpout发出的每一个元组。 SplitSentence的关键方法是execute,它将句子拆分成单词,并发出每个单词作为新的元组。另一个重要的方法是declareOutputFields,其中声明了Bolt输出元组的架构,这个方法声明它发出一个域为“word”的元组。 SplitSentence对句子中的每个单词发射一个新的Tuple,WordCount在内存中维护每个单词出现次数的映射,WordCount每收到一个单词,都会更新内存中的统计状态。 SplitSentence的实现代码如下: public class SplitSentence implements IBasicBolt{ public void prepare(Map conf, TopologyContext context) { } public void execute(Tuple tuple, BasicOutputCollector collector) { String sentence = tuple.getString(0); for(String word: sentence.split(" ")) { collector.emit(new Values(word)); } } public void cleanup() { } public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("word")); } } WordCount的实现代码如下: public class WordCount implements IBasicBolt { private Map<String, Integer> _counts = new HashMap<String, Integer>(); public void prepare(Map conf, TopologyContext context) { } public void execute(Tuple tuple, BasicOutputCollector collector) { String word = tuple.getString(0); int count; if(_counts.containsKey(word)) { count = _counts.get(word); } else { count = 0; } count++; _counts.put(word, count); collector.emit(new Values(word, count)); } public void cleanup() { } public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("word", "count")); } } 4. Topology运行 Topology运行有两种模式:本地模式和分布式模式。这两种模式的接口区别很大,使用场景也不相同。另外,下面还将介绍Topology的运行流程、方法调用过程以及并行度等。1. Topology运行模式 Topology的运行模式可以分为本地模式和分布式模式,模式可以在配置文件中和代码中设置。 (1)本地模式 Storm用一个进程中的线程来模拟所有的Spout和Bolt。本地模式对开发和测试来说比较有用。storm-starter中的Topology是以本地模式运行的,可以看到Topology中的每一个组件发射的消息。示例代码如下: Config conf = new Conf?ig(); conf.setDebug(true); conf.setNumWorkers(2); LocalCluster cluster = new LocalCluster(); cluster.submitTopology("test", conf, builder.createTopology()); Utils.sleep(10000); cluster.killTopology("test"); cluster.shutdown(); 首先,这段代码通过定义一个LocalCluster对象来定义一个进程内的集群。提交Topology给这个虚拟的集群和提交Topology给分布式集群相同。通过调用submitTopology方法来提交Topology,共有3个参数:要运行的Topology的名称、一个配置对象,以及要运行的Topology本身。 Topology是以名称来唯一区别的,可以用这个名称来杀掉该Topology,而且必须显式地杀掉,否则它会一直运行。 conf对象可以配置内容很多,下面两个是最常见的:TOPOLOGY_WORKERS (setNumWorkers):定义希望集群分配多少个工作进程来执行这个Topology。Topology中的每个组件都需要线程来执行。每个组件到底用多少个线程是通过setBolt和setSpout来指定的。这些线程都运行在工作进程中。每一个工作进程包含一些节点的一些工作线程。例如,指定300个线程,60个进程,那么每个工作进程中要执行6个线程,而这6个线程可能属于不同的组件(Spout或Bolt)。可以调整每个组件的并行度以及这些线程所在的进程数量来调整Topology的性能。TOPOLOGY_DEBUG (setDebug):当它设置为true时,Storm会记录下每个组件发射的每条消息。这在本地环境调试Topology时很有用,但是在生产环境中如果这么做,则会影响性能。 (2)分布式模式 Storm由若干节点组成。提交Topology给Nimbus时,也会提交Topology代码。Nimbus负责分发代码和给Topolgoy分配工作进程。如果一个工作进程挂掉了,Nimbus节点会将其重新分配到其他节点。分布式模式提交拓扑的代码如下: StormSubmitter.submitTopology(topologyName, topologyConf?ig, builder.createTopology()); 在Storm代码编写完成之后,需要打包成JAR包放到Nimbus中运行。在打包时,不需要把依赖的JAR都打进去,否则运行时会出现重复的配置文件错误导致Topology无法运行,因为在Topology运行之前,会加载本地的storm.yaml配置文件。 在Nimbus运行的命令如下。 storm jar StormTopology.jar mainclass args 2. Topology运行流程 在Topology的运行流程中,有几点需要特别说明。 1)提交Topology后,Storm会把代码先存放到Nimbus节点的inbox目录下;之后,把当前Storm运行的配置生成一个stormconf.ser文件放到Nimbus节点的stormdist目录中,此目录中同时还有序列化之后的Topology代码文件。 2)在设定Topology关联的Spout和Bolt时,可以同时设置当前Spout和Bolt的Executor和Task数量。在默认情况下,一个Topology的Task总和与Executor的总和一致。之后,系统根据Worker的数量,尽量将这些Task平均分配到不同的Worker上执行。Worker在哪个Supervisor节点上运行是由Storm本身决定的。 3)在任务分配好之后,Nimbus节点将任务的信息提交到ZooKeeper集群,同时在ZooKeeper集群中有Workerbeats,这里存储了当前Topology所有Worker进程的心跳信息。 4)Supervisor节点不断轮询ZooKeeper集群,在ZooKeeper的assignments中保存了所有Topology的任务分配信息、代码存储目录、任务之间的关联关系等,Supervisor通过轮询此节点的内容来领取自己的任务,启动Worker进程运行。 5)一个Topology运行之后,不断通过Spout来发送流,通过Bolt来不断处理接收到的流,流是无界的。最后一步会不间断地执行,除非手动结束该Topology。 3. Topology的方法调用流程 Topology中的流处理时,调用方法的过程如图3-16所示。 Topology方法调用的过程有如下一些要点: 1)每个组件(Spout或者Bolt)的构造方法和declareOutputFields方法都只被调用一次。 2)open方法和prepare方法被调用多次。在入口函数中设定的setSpout或者setBolt中的并行度参数是指Executor的数量,是负责运行组件中的Task的线程数量,此数量是多少,上述两个方法就会被调用多少次,在每个Executor运行时调用一次。 3)nextTuple方法和execute方法是一直运行的,nextTuple方法不断发射Tuple,Bolt的execute不断接收Tuple进行处理。只有这样不断地运行,才会产生无界的Tuple流,体现实时性。这类似于Java线程的run方法。 4)提交一个Topology之后,Storm创建Spout/Bolt实例并进行序列化。之后,将序列化的组件发送给所有任务所在的节点(即Supervisor节点),在每一个任务上反序列化组件。 5)Spout和Bolt之间、Bolt和Bolt之间的通信,通过ZeroMQ的消息队列实现。 6)图3-16没有列出ack和fail方法,在一个Tuple成功处理之后,需要调用ack方法来标记成功,否则调用fail方法标记失败,重新处理该Tuple。 图5 Topology流处理过程图 4. Topology并行度 在Topology的执行单元中,有几个和并行度相关的概念。 (1)Worker 每个Worker都属于一个特定的Topology,每个Supervisor节点的Worker可以有多个,每个Worker使用一个单独的端口,Worker对Topology中的每个组件运行一个或者多个Executor线程来提供Task的执行服务。 (2)Executor Executor是产生于Worker进程内部的线程,会执行同一个组件的一个或者多个Task。 (3)Task 实际的数据处理由Task完成。在Topology的生命周期中,每个组件的Task数量不会变化,而Executor的数量却不一定。Executor数量小于等于Task的数量,在默认情况下,二者是相等的。 在运行一个Topology时,可以根据具体的情况来设置不同数量的Worker、Task、Executor,设置的位置也可以在多个地方。 1)Worker设置:可以设置yaml中的topology.workers属性。在代码中通过Conf?ig的setNumWorkers方法设定。 2)Executor设置:通过Topology的入口类中的setBolt、setSpout方法的最后一个参数指定,如果不指定,则使用默认值1。 3)Task设置:在默认情况下,和executor数量一致。在代码中通过TopologyBuilder的setNumTasks方法设定具体某个组件的Task数量。 5. 终止Topology 在Nimbus启动的节点上,使用下面的命令来终止一个Topology的运行。 storm kill topologyName 执行kill之后,通过UI界面查看Topology状态,其先变成KILLED状态,清理完本地目录和ZooKeeper集群中与当前Topology相关的信息之后,此Topology将彻底消失。 6.Topology跟踪 提交Topology后,可以在Storm UI界面查看整个Topology运行的过程。 如下 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5989714.html,如需转载请自行联系原作者

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

【swift学习笔记】六.访facebook登录页面

代码最下边有下载地址。 做这个demo的主要心得就是自适应所有的屏幕,要先布局大的框架,再一步一步设置小的细节。 看一下效果 再看一下自动适应所有屏幕的效果: keyboard打开时整个frame上移一个keyboard的高度 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // btn loginBtn.layer.cornerRadius = 3 // text userText.delegate = self passwordText.delegate = self NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillShow(notification: NSNotification) { if isMovied { return } isMovied = true if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { UIView.animateWithDuration(0.25, animations: { self.view.frame.origin.y -= keyboardSize.height } ) } } func keyboardWillHide(notification: NSNotification) { isMovied = false if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { UIView.animateWithDuration(0.25, animations: { self.view.frame.origin.y += keyboardSize.height }) } } 别的就没有什么技术点了,大家有时间下载代码看一下吧。 源代码:FaceBookLoginView.zip 本文转自lpxxn博客园博客,原文链接:http://www.cnblogs.com/li-peng/p/5584236.html,如需转载请自行联系原作者

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

《Linux信息安全实用教程》学习笔记

在GRUB中设置密码 vi /etc/grub.conf 增加: password = 654321 或者: password --md5 (MD5值) 使用yyd用户能以root用户执行所有命令 vi /etc/sidoers yyd ALL=(ALL)ALL Linux自带MD5加密 /sbin/grub-md5-crypt 限制su命令的滥用 使用PAM可以对切换到超级用户的限制,PAM可以禁止除在wheel组以外的任何人使用su命令转换成root vi /etc/pam.d/su 去掉这两行左边的注释符“#”: #auth sufficient /libsecurity/$ISA/pam_wheel.so trust use_uid #auth required /lib/security/$SIA/panm_wheel.so use_uid 使用过的命令查看以及配置修改 在“~/.bash_history”文件中默认保存了500条使用过的命令,只要按方向键中的上就可以调出来 vi /etc/profile 修改HISTSIZE的值: HISTSIZE = 10 可以保存的旧命令为10条。 访问控制 hosts.allow和hosts.deny是tcpd服务器主配置文件,tcpd服务器可以控制外部IP对本机服务的访问 vi /etc/hosts.allow ALL:127.0.01 ftp:192.168.0.0/255.255.255.0 第一行是允许访问本机所以服务进程 第二行是允许192.168.0.1~192.168.0.254的IP对本机ftp的服务访问 设置FTP服务器不允许匿名登录 vi /etc/vsftpd/vsftp.conf anonymous_enable = NO 把YES改为NO便可。 配置shadow文件禁止用户登录 这方法只是实现改变此用户密码导致不能登录 vi /etc/shadow 在yyd行,在第一个冒号之后加上一个星号 * 终端禁止yyd用户登录 usermod -L yyd 修改密码最短长度 vi /etc/login.defs PASS_MIN_LEN 5 将5改为10,则最短密码为10。 禁止系统响应ping请求(需要安装iptables) vi /etc/rc.d/ec/local touch /var/lock/subsys/local echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all 运行脚本 ./rc.local 在Linux启动过程中,禁止Ctrl + Alt +Del 重新启动 vi /ect/inittab 注释掉下面这行,用“#”: ca::ctrlaltdel:/sbin/shutdown -tb -r now 通过中断后台启动进程格式 进程命令 & 调度启动(at命令) 日志 Linux日志存储在/var/log目录中 1、当前登录的每个用户的信息记录在utmp文件中 2、每个用户最后的登录信息记录在lastlog文件中 3、每个用户登录、注销以及系统启动、停机的时间信息记录在wtmp文件中,所以记录都包含时间戳 who、who -m、who -q查看系统中用户登录情况 last:往回搜索自从文件wtmp创建以来最近登陆过的用户。 lastlog:列出用户最后登录的时间和登录终端的地址,如果此用户从来没有登录,则显示:**Never logged in**。 sa:汇总先前命令执行的信息。 access-log:记录HTTP/web的传输。 secure:巨鹿登录系统存取资料的信息。 btmp:记录失败的记录。 messages:从syslog记录信息(又得是连接到syslog文件)。 sudolog:记录使用sudo发出的命令。 sulog: 记录使用su命令的使用。 utmp:记录当前登录的每个用户。 wtmp:一个用户每次登录进入和退出时间的永久记录。 xferlog:记录FTP会话。 启动syslog服务 service syslog start 配置文件/etc/syslog.conf # Log all kernel messages to the console. # Logging much else clutters up the screen. #kern.* /dev/console # Log anything (except mail) of level info or higher. # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none /var/log/messages # The authpriv file has restricted access. authpriv.* /var/log/secure # Log all the mail messages in one place. mail.* -/var/log/maillog # Log cron stuff cron.* /var/log/cron # Everybody gets emergency messages *.emerg * # Save news errors of level crit and higher in a special file. uucp,news.crit /var/log/spooler # Save boot messages also to boot.log local7.* /var/log/boot.log syslog.conf 行的基本语法是: [消息类型].[优先级] [处理方案] ---> facility.priority log_location 注意:中间的分隔符必须是Tab 字符! 消息类型 -说明 authpriv -包括特权信息如用户名在内的认证活动 cron-与cron和at有关的计划任务信息 daemon-与inetd守护进程有关的后台进程信息 kern-内核信息,首先通过klogd传递 lpr-与打印服务有关的信息 mail-与电子邮件有关的信息 mark-syslog内部功能用于生成时间戳 news-来自新闻服务器的信息 syslog-由syslog生成的信息 user-由用户程序生成的信息 uucp-由uucp生成的信息 local0-local7-与自定义程序使用 优先级-说明 emerg-该系统不可用,等同panic alert-需要立即被修改的条件 crit-阻止某些工具或子系统功能实现的错误条件 err-阻止工具或某些子系统部分功能实现的错误条件,等同error warning-预警信息,等同warn notice-具有重要性的普通条件 info-提供信息的消息 debug-不包含函数条件或问题的其他信息 none-没有重要级,通常用于排错 处理方案 -说明 file -指定文件的绝对路径 teminal-输出到终端设备 @host-输出到远程日志服务器 username-发送到指定用户 日志管理工具 logrotate 配置文件/etc/logotate.conf telnet修改默认端口号 vi /etc/services telnet 23/tcp telnet 23/udp 将23改为其他数字。 telnet安全设置 /ect/xinetd.dtelnet ssh基于密钥的验证方法 ssh -keygen -t rsa VNC 能够将完整的窗口画面通过网络传输到另外一台计算机屏幕上。 防火墙 iptables 读书心得: 用的是RED HAT 9 的 Linux 操作系统,发现其实linux的系统做服务器真心好,我现在在管理一台学校的Win2003的服务器,虽然全图形界面话,用着很容易上手,但是如果是用的apache+PHP+MYSQL的话,配置,安全保护等弄起来很复杂,而且若是IIS的话,猜测漏洞比较多,会比较难管理吧。 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3464340.html如需转载请自行联系原作者

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

Android Map开发基础知识学习笔记

注册Android地图API密钥 运行:keytool -list -keystore ~/.android/debug.keystore 用得到的MD5码到http://code.google.com/intl/zh-CN/android/maps-api-signup.html注册API密钥。参考: http://www.cnblogs.com/feisky/archive/2010/01/17/1650083.html 注册完成后会得到如下的网页: 您的密钥是: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 此密钥适用于所有使用以下指纹所对应证书进行验证的应用程序: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX 下面是一个xml格式的示例,帮助您了解地图功能: <com.google.android.maps.MapView android:layout_width="fill_parent" android:layout_height="fill_parent"android:apiKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" /> 模拟器设置 建立一个"Google Inc.:Google APIs:3"的模拟器。 手机终端需要支持Google Add-ons 作为与Google合作的手机终端的制造商,如果想在自己的Android终端中集成Google的一些应用,例如map,market,picasa,sync等,需要和Google签约,这样Google会有专人帮你将这一系列服务整合到你的平台中来。 作为没有和Google合作的手机终端的制造商,我们可以使用破解的方法将Add-ons中的运行库整合到自己的framework中来(build到手机终端的system.img中)。操作如下: 1.在Android中,额外支持GoogleAdd-ons(Google Maps),需要将如下档案(从标准的SDK中pull出来的,也可以从GPhone中pull出来)打包进System.img。GoogleAdd-ons只需要1--2,Goolge Maps(Google的地图程序)需要1--5: 1)system/frameworkcom.google.android.maps.jar 2)system/etc/permissionscom.google.android.maps.xml 3)system/frameworkcom.google.android.gtalkservice.jar 4)system/etc/permissionscom.google.android.gtalkservice.xml 5)system/appMaps.apk (Google Maps v3.0) 2.源码:Android Cupcake Release(经测试,在donut平台同样适用。) 1)编译源码(为了生成out/target目录中Android最原始的东西) 2)将以上文件加入out/target/product/generic相应目录,在源码根目录使用make snod打包,获得新的system.img 权限和Maps库设置 在manifest.xml中设置全相应的权限,比如: <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> 在manifest.xml中加上要用的maps库: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.package.name"> ... <application android:name="MyApplication"> <uses-library android:name="com.google.android.maps"/> ... </application> ... </manifest> Maps库分析 Maps库提供了十几个类,具体可以参考这里http://code.google.com/intl/ja/android/add-ons/google-apis/reference/index.html,包括Mapview,MapController,MapActivity等。 (1)MapController 控制地图移动,伸缩,以某个GPS坐标为中心,控制MapView中的view组件,管理Overlay,提供View的基本功能。使用多种地图模式(地图模式(某些城市可实时对交通状况进行更新),卫星模式,街景模式)来查看Google Map。 常用方法:animateTo(GeoPoint point)setCenter(GeoPoint point)setZoom(int zoomLevel)等。 (2)MapView Mapview是用来显示地图的view,它派生自android.view.ViewGroup。当MapView获得焦点,可以控制地图的移动和缩放。 地图可以以不同的形式来显示出来,如街景模式,卫星模式等,通过setSatellite(boolean)setTraffic(boolean), setStreetView(boolean)方法。 MapView只能被MapActivity来创建,这是因为mapview需要通过后台的线程来连接网络或者文件系统,而这些线程要由mapActivity来管理。 需要特别说明的一点是,android 1.5中,map的zoom采用了built-in机制,可以通过setBuiltInZoomControls(boolean)来设置是否在地图上显示zoom控件。 常用方法:getController()getOverlays()setSatellite(boolean)setTraffic(boolean),setStreetView(boolean)setBuiltInZoomControls(boolean)等。 (3)MapActivity 管理Activity的生命周期,为mapview建立及取消对map service的连接。 MapActivity是一个抽象类,任何想要显示MapView的activity都需要派生自MapActivity。并且在其派生类的onCreate()中,都要创建一个MapView实例,可以通过MapViewconstructor (然后添加到View中ViewGroup.addView(View))或者通过layout XML来创建。 (4)Overlay Overlay是覆盖到MapView的最上层,可以扩展其ondraw接口,自定义在MapView中显示一些自己的东西。MapView通过MapView.getOverlays()对Overlay进行管理。 除了Overlay这个基类,Google还扩展了2个比较有用的Overlay 1)MylocationOverlay—集成了Android.location中接收当前坐标的接口,集成SersorManager中CompassSensor的接口 我们只需要enableMyLocation(),enableCompass就可以让我们的程序拥有实时的MyLocation以及Compass功能(Activity.onResume()中)。 2)ItemlizedOverlay—管理一个OverlayItem链表,用图片等资源在地图上作风格相同的标记。 (5)Projection:MapView中GPS坐标与设备坐标的转换(GeoPoint和Point)。 一个简单的小例子 用一个小程序来演示一下android中地图功能的开发。主要功能是实现了地图的缩放,添加了菜单,从而可以手动选择地图的显示模式等。 Step1:新建一个android project,注意这里要选择的buildtarget为"GoogleAPIs" Step 2:修改menifest文件: <?xmlversion="1.0"encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.map.prac" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon"android:label="@string/app_name"> <uses-library android:name="com.google.android.maps" /> <activity android:name=".MapViewPrac2" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest> Step 3:修改layout文件,main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="???????????????????????????????????" /> </LinearLayout> 这里需要将api key中的????????????改成你自己申请到的api key. Step4:修改代码: package feisky.navigation; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends MapActivity { // 地图显示控制相关变量定义 private MapView map=null; private MapController mapCon; // 菜单项 final private int menuMode=Menu.FIRST; final private int menuExit=Menu.FIRST+1; private int chooseItem=0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取MapView map=(MapView)findViewById(R.id.map); // 设置显示模式 map.setTraffic(true); map.setSatellite(false); map.setStreetView(true); // 设置可以缩放 map.setBuiltInZoomControls(true); // 设置初始地图的中心位置 GeoPoint geoBeijing=new GeoPoint((int)(39.95*1000000), (int)(116.37*1000000)); mapCon=map.getController(); mapCon.setCenter(geoBeijing); } @Override public boolean onCreateOptionsMenu(Menu menu) { // 建立菜单 menu.add(0,menuMode,0,"地图模式"); menu.add(0, menuExit, 1, "退出"); return super.onCreateOptionsMenu(menu); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case menuExit: finish(); break; case menuMode: Dialog dMode=new AlertDialog.Builder(this) .setTitle("地图模式设置") .setSingleChoiceItems(R.array.MapMode, chooseItem, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { chooseItem=which; } }) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: map.setSatellite(true); //map.setTraffic(false); //map.setStreetView(false); break; case 1: //map.setSatellite(false); map.setTraffic(true); //map.setStreetView(false); break; case 2: //map.setSatellite(false); //map.setTraffic(false); map.setStreetView(true); break; default: break; } } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .create(); dMode.show(); break; default: break; } return super.onMenuItemSelected(featureId, item); } @Override protected boolean isRouteDisplayed() { return false; } } 本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/archive/2010/01/20/1652230.html,如需转载请自行联系原作者

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

MyGeneration学习笔记(11) :dOOdad的架构(Architectures)

前面10篇介绍了使用dOOdads做ORM映射的基本使用方法和我在使用过程中的总结的一些技巧,这里我再对dOOdads项目做一个概要的总结: 1. 使用dOOdad的概要步骤: (1) 创建解决方案,将dOOdad项目加入该解决方案; (2) 使用MyGeneration的dOOdads存储过程模板生成存储过程,并手工写入数据库中; (3) 使用MyGeneration的dOOdads BusinessEntity模板和ConcreteClass模板生成实体类;并添加到项目中; (4) 配置数据库连接字符串; That's all! So Easy.详细步骤及我在使用中遇到的问题,我以前都有记录: http://www.cnblogs.com/happyhippy/category/79938.html 2. dOOdad的架构: (1) 模型(From MyGeneration): (2) 架构: 本文转自Silent Void博客园博客,原文链接:http://www.cnblogs.com/happyhippy/archive/2007/04/16/715501.html,如需转载请自行联系原作者

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

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

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

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

用户登录
用户注册