首页 文章 精选 留言 我的

精选列表

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

Android开发学习笔记:RadioButton和CheckBox浅析

一.RadioButton单选按钮 RadioButton(单选按钮)在Android开发中应用的非常广泛,比如一些选择项的时候,会用到单选按钮。它是一种单个圆形单选框双状态的按钮,可以选择或不选择。在RadioButton没有被选中时,用户能够按下或点击来选中它。但是,与复选框相反,用户一旦选中就不能够取消选中。 实现RadioButton由两部分组成,也就是RadioButton和RadioGroup配合使用.RadioGroup是单选组合框,可以容纳多个RadioButton的容器.在没有RadioGroup的情况下,RadioButton可以全部都选中;当多个RadioButton被RadioGroup包含的情况下,RadioButton只可以选择一个。并用setOnCheckedChangeListener来对单选按钮进行监听 下面的具体的例子: MainActivity.java packagecom.android.radiobutton; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.RadioGroup; importandroid.widget.Toast; publicclassMainActivityextendsActivity{ //声明RadioGroup RadioGroupraGroup1,raGroup2; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //通过findViewById获得RadioGroup对象 raGroup1=(RadioGroup)findViewById(R.id.radioGroup1); //添加事件监听器 raGroup1.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){ @Override publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){ //TODOAuto-generatedmethodstub if(checkedId==R.id.radioBtn1){ Toast.makeText(MainActivity.this,"你来自广东省",Toast.LENGTH_LONG).show(); } elseif(checkedId==R.id.radioBtn2){ Toast.makeText(MainActivity.this,"你来自广西省",Toast.LENGTH_LONG).show(); } else{ Toast.makeText(MainActivity.this,"你来自湖南省",Toast.LENGTH_LONG).show(); } } }); raGroup2=(RadioGroup)findViewById(R.id.radioGroup2); raGroup2.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){ @Override publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){ //TODOAuto-generatedmethodstub if(checkedId==R.id.radioBtn4){ Toast.makeText(MainActivity.this,"你的性别是男",Toast.LENGTH_LONG).show(); } else{ Toast.makeText(MainActivity.this,"你的性别是女",Toast.LENGTH_LONG).show(); } } }); } } main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello1" /> <RadioGroup android:id="@+id/radioGroup1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/radioBtn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn1" /> <RadioButton android:id="@+id/radioBtn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn2" /> <RadioButton android:id="@+id/radioBtn3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn3" /> </RadioGroup> <!--在两个RadioGroup之间画条横线--> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#ffffff" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello2" /> <RadioGroup android:id="@+id/radioGroup2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/radioBtn4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn4" android:textColor="#ffffff" /> <RadioButton android:id="@+id/radioBtn5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn5" /> </RadioGroup> </LinearLayout> strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello1">你来自哪个省</string> <string name="hello2">你的性别是</string> <string name="app_name">单选按钮测试</string> <string name="radioBtn1">广东</string> <string name="radioBtn2">广西</string> <string name="radioBtn3">湖南</string> <string name="radioBtn4">男</string> <string name="radioBtn5">女</string> </resources> 效果图: RadioButton的另一种效果: 要实现上面的效果,只要在main.xml布局文件中的<RadioButton/>加入android:button="@null" android:drawableRight="@android:drawable/btn_radio"即可,代码如下所示: <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello1" /> <RadioGroup android:id="@+id/radioGroup1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/radioBtn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn1" android:button="@null" android:drawableRight="@android:drawable/btn_radio" /> <RadioButton android:id="@+id/radioBtn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn2" android:button="@null" android:drawableRight="@android:drawable/btn_radio" /> <RadioButton android:id="@+id/radioBtn3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn3" android:button="@null" android:drawableRight="@android:drawable/btn_radio" /> </RadioGroup> <!--在两个RadioGroup之间画条横线--> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#ffffff" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello2" /> <RadioGroup android:id="@+id/radioGroup2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/radioBtn4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn4" android:textColor="#ffffff" android:button="@null" android:drawableRight="@android:drawable/btn_radio" /> <RadioButton android:id="@+id/radioBtn5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/radioBtn5" android:button="@null" android:drawableRight="@android:drawable/btn_radio" /> </RadioGroup> </LinearLayout> 二.CheckBox复选按钮 CheckBox复选按钮是一种有双状态按钮的特殊类型,可以选中或者不选中。可以现在布局文件中定义多选按钮,然后对每一个多选按钮进行事件监setOnCheckedChangeListener,通过isChecked来判断选项是否被选中 下面是具体的例子: MainActivity.java packagecom.android.checkbox; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.CheckBox; importandroid.widget.CompoundButton; importandroid.widget.Toast; importandroid.widget.CompoundButton.OnCheckedChangeListener; publicclassMainActivityextendsActivity{ //声明复选按钮 privateCheckBoxcBox1; privateCheckBoxcBox2; privateCheckBoxcBox3; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //通过findViewById获得CheckBox对象 cBox1=(CheckBox)findViewById(R.id.checkbox1); cBox2=(CheckBox)findViewById(R.id.checkbox2); cBox3=(CheckBox)findViewById(R.id.checkbox3); //注册事件监听器 cBox1.setOnCheckedChangeListener(listener); cBox2.setOnCheckedChangeListener(listener); cBox3.setOnCheckedChangeListener(listener); } //响应事件 privateOnCheckedChangeListenerlistener=newOnCheckedChangeListener(){ @Override publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked) { //cBox1被选中 if(buttonView.getId()==R.id.checkbox1){ if(isChecked){ Toast.makeText(MainActivity.this,"你喜欢足球",Toast.LENGTH_LONG).show(); } } //cBox2被选中 elseif(buttonView.getId()==R.id.checkbox2){ if(isChecked){ Toast.makeText(MainActivity.this,"你喜欢篮球",Toast.LENGTH_LONG).show(); } } //cBox3被选中 elseif(buttonView.getId()==R.id.checkbox3){ if(isChecked){ Toast.makeText(MainActivity.this,"你喜欢排球",Toast.LENGTH_LONG).show(); } } } }; } main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:textSize="20sp" android:textStyle="bold" android:textColor="#FFFFFF" /> <CheckBox android:id="@+id/checkbox1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/football" android:textSize="16sp" /> <CheckBox android:id="@+id/checkbox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/basketball" android:textSize="16sp" /> <CheckBox android:id="@+id/checkbox3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/volleyball" android:textSize="16sp" /> </LinearLayout> strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">你喜欢的运动是</string> <string name="app_name">复选按钮测试</string> <string name="football">足球</string> <string name="basketball">篮球</string> <string name="volleyball">排球</string> </resources> 效果图: 三.总结 RadioButton和CheckBox的区别: 1、单个RadioButton在选中后,通过点击无法变为未选中单个CheckBox在选中后,通过点击可以变为未选中 2、一组RadioButton,只能同时选中一个一组CheckBox,能同时选中多个 3、RadioButton在大部分UI框架中默认都以圆形表示CheckBox在大部分UI框架中默认都以矩形表示 RadioButton和RadioGroup的关系: 1、RadioButton表示单个圆形单选框,而RadioGroup是可以容纳多个RadioButton的容器 2、每个RadioGroup中的RadioButton同时只能有一个被选中 3、不同的RadioGroup中的RadioButton互不相干,即如果组A中有一个选中了,组B中依然可以有一个被选中 4、一般情况下,一个RadioGroup中至少有2个RadioButton 5、一般情况下,一个RadioGroup中的RadioButton默认会有一个被选中,并建议您将它放在RadioGroup中的起始位置 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/652042

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

android学习之-获得手机屏幕大小

主类 packagesucre.android; importandroid.app.Activity; importandroid.os.Bundle; importandroid.util.DisplayMetrics; importandroid.widget.TextView; /** *取得手机屏幕的大小,用到了android.util下的DisplayMetrics *@authorqiaolei * */ publicclassEXT03_05extendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //定义DisplayMetrics对象 DisplayMetricsdm=newDisplayMetrics(); //根据windowManager获取Metrics //调用getWindowManager()之后,会取得现有的Activity的Handler,然后调用getDefaultDisplay() //取得屏幕宽高将其放到dm中 getWindowManager().getDefaultDisplay().getMetrics(dm); //获取屏幕的宽和高 Stringstr="手机屏幕的分辨率为:"+dm.widthPixels+"x"+dm.heightPixels; //定义要显示str内容Textview TextViewtv=(TextView)findViewById(R.id.myTextView); //将内容放到TextView中 tv.setText(str); } } 本文转自sucre03 51CTO博客,原文链接:http://blog.51cto.com/sucre/742952,如需转载请自行联系原作者

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

学习OpenStack之 (3):Devstack Screen 使用技巧

Devstack环境中,openstack运行在一个screen中,每个service运行在一个window中。我总结的几个tips: 0. 注意需要使用screen启动用户来进行一下操作 1. 查看当前用户开启的所有screen:screen -list s1@dev:~/devstack$ screen -listThere is a screen on:9606.stack (12/12/2014 11:22:54 AM) (Detached)1 Socket in /var/run/screen/S-s1. 2. screen attach:screen -r <screen id,比如上图中的9606>(注:openstack的rejoin-stack.sh也是调用该命令来reattach openstack) (打*的是当前的window) 3. screen dettach:screen -d 4. 移到下一个window:CRTL + A + n 5. 移到前一个window:CRTL + A + p 6. 直接跳到 0 ~9 的某window,比如上图中的第7个:CRTL + A + 7 7. 直接跳到第10个以后的window,比如第17个:CRTL + A + ',输入 17 8. 在screen window中滚动屏幕:开始滚动模式CTRL + [,然后可以使用上下左右键滚屏,按CTRL + ]退出滚动模式 9. 重启某个Cinder service: (1)CRTL + a + <n,比如18 c-vol window> (2)CRTL + c, 杀掉进程 (3)按向上键,出现之前运行的命令,输入即重启c-vol service 10. 按CRTL + a, 稍等一秒,再按 " (shift + ' 所在键)显示screen中所有window的列表 (四个键连续按是不行的 :)) 11. 默认的所有screen 快捷键 本文转自SammyLiu博客园博客,原文链接:http://www.cnblogs.com/sammyliu/p/4159475.html,如需转载请自行联系原作者

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

Android学习笔记--Activity的生命周期

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 参考文档:安装目录/docs/index.html Activity的生命周期函数 onCreate(Activity被第一个创建时),onReStart,onStart(Activity可视的时候),onDestroy,onPause(Activity暂停状态),onResume(Activity可被获得焦点的时候),onStop(Activity不可见的时候) 启动一个新的Activity会依次调用onCreate,onStart,onResume 调用另外一个Activity会依次调用onPause(第一个),onCreate(第二个),onStart(第二个),onResume(第二个),onStop(第一个) 调用返回按钮Activty会依次调用onPause(第二个),onReStart(第一个),onStart(第一个),onResume(第一个),onStop(第二个),onDestory(第二个) onDestory()被调用的时机1.明确调用finish方法2.系统自适应释放 Task基本概念(栈中的所有Activity)栈压栈,弹栈(后进先出原则) Task运行过程,当应用程序启动之后,运行第一个Activity被压入栈中(显示会时栈中最顶部的Activity) 3.模态化窗体(对话框) 在AndroidManifest.xml文件中<Activityandroid:name=".MofityActivity" android:label="MofityActivity" android:theme="@anroid:style/Theme.Dialog" /> 可被杀死的方法onStop,onPause,onDestory 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360576,如需转载请自行联系原作者

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

Android学习笔记--工程创建及目录结构

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 一,新建project New->androidproject->projectname->buildtarget(开发的版本选择)->apllcationname->packagename->createactivity(显示界面)->minsdkversion(最低兼容sdk版本) 二,android程序的目录结构 Src==>编写的源文件 Gen==>引用程序的资源文件(不要修改) Android==>源文件jar文件 Assets==>放置任何文件 Res==>此处放置会在gen中生成相应ID Drawable放置图片分为多个分辨率图片hdpi,ldpi,mdpi高中低 Layout布局方式 Values adnroidManifest.xml全局配置文件 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360580,如需转载请自行联系原作者

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

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,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

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

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文件系统,支持十年生命周期更新。

用户登录
用户注册