首页 文章 精选 留言 我的

精选列表

搜索[动态工作流],共10000篇文章
优秀的个人博客,低调大师

界面无小事(七):使用代码动态增删布局

界面无小事(一):RecyclerView+CardView了解一下界面无小事(二):让RecyclerView展示更多不同视图界面无小事(三):用RecyclerView + Toolbar做个文件选择器界面无小事(四):来写个滚动选择器吧!界面无小事(五):自定义TextView界面无小事(六):来做个好看得侧拉菜单!github传送门 目录 效果图 前言 布局文件 实现 最后 效果图 不多废话, 先上图, 有兴趣再看下去: 效果图 前言 这篇是之前的一篇旧文改的, 也是想将这篇放入自己的界面无小事专题, 所以当成新篇章来写, 绝对不是为了什么日更之类的事情哦(手动滑稽)~. 布局文件 先来看看布局文件, 不是很复杂, 但是涉及到之后java部分的代码, 所以必须都贴出来. 不过你可以看下预览图就好: 布局预览图 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.so.moreview.ui.activity.MainActivity"> <LinearLayout android:id="@+id/ll_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/eight_dp"> <LinearLayout android:id="@+id/ll_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/darker_gray" android:orientation="vertical" android:padding="@dimen/eight_dp" tools:ignore="UselessParent"> <EditText android:id="@+id/et_item" android:layout_width="match_parent" android:layout_height="@dimen/forty_dp" android:background="@android:color/white" android:gravity="center_vertical" android:inputType="textMultiLine" android:textSize="@dimen/sixteen_sp" tools:ignore="LabelFor" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/eight_dp"> <ImageButton android:id="@+id/ib_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:background="@drawable/add" android:contentDescription="" tools:ignore="ContentDescription" /> </RelativeLayout> </LinearLayout> </LinearLayout> </ScrollView> 实现 LinkedList<ImageButton> mAddList; mAddList.add(curView, btAdd); LinkedList<ImageButton> mDelList; mDelList.add(curView, btDel); 这里我使用LinkedList<ImageButton>实例存储ImageButton, 就是为了让增删的时候方便一些. 最关键的是增删按钮的代码: 添加条目 /** * @param v 添加一个新条目 */ private void addItem(View v) { if (v == null) { return; } // 1. 根据传入的v, 判断是mListAddBtn中的哪一个 int curView = -1; for (int i = 0; i < mAddList.size(); i++) { if (mAddList.get(i) == v) { curView = i; break; } } // 2. 根据获取的值添加控件 if (curView >= 0) { curView++; // ll_item LinearLayout ll = new LinearLayout(MainActivity.this); LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); llParams.setMargins(0, UIUtil.dp2px(8), 0, 0); ll.setLayoutParams(llParams); ll.setBackgroundColor(ContextCompat.getColor(this, android.R.color.darker_gray)); ll.setPadding(UIUtil.dp2px(8), UIUtil.dp2px(8), UIUtil.dp2px(8), UIUtil.dp2px(8)); ll.setOrientation(LinearLayout.VERTICAL); // et_item EditText et = new EditText(MainActivity.this); LinearLayout.LayoutParams etParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, mEtHeight); et.setLayoutParams(etParams); et.setBackgroundColor(ContextCompat.getColor(this, android.R.color.white)); et.setGravity(Gravity.CENTER_VERTICAL); et.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE); et.setTextSize(16); et.setId(mEtId); ll.addView(et); RelativeLayout rl = new RelativeLayout(MainActivity.this); RelativeLayout.LayoutParams rlParams = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); rlParams.setMargins(0, UIUtil.dp2px(8), 0, 0); rl.setLayoutParams(rlParams); // ib_add ImageButton btAdd = new ImageButton(MainActivity.this); RelativeLayout.LayoutParams btAddParams = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); btAddParams.addRule(RelativeLayout.ALIGN_PARENT_END); btAdd.setLayoutParams(btAddParams); btAdd.setBackgroundResource(R.drawable.add); btAdd.setId(mBtnAddId); btAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addItem(v); } }); rl.addView(btAdd); mAddList.add(curView, btAdd); // ib_del ImageButton btDel = new ImageButton(MainActivity.this); RelativeLayout.LayoutParams btDelParams = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); btDelParams.setMargins(0, 0, UIUtil.dp2px(8), 0); btDelParams.addRule(RelativeLayout.LEFT_OF, mBtnAddId); btDel.setLayoutParams(btDelParams); btDel.setBackgroundResource(R.drawable.del); btDel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { delItem(v); } }); rl.addView(btDel); mDelList.add(curView, btDel); ll.addView(rl); mLlContent.addView(ll, curView); mBtnAddId++; mEtId++; } } 看起来有些长, 但是对照布局文件来看, 就非常简单了, 就是用java代码把布局文件里写的再写一遍. 删除条目 /** * @param v 删除一个新的EditText条目 */ private void delItem(View v) { if (v == null) { return; } int curView = -1; for (int i = 0; i < mDelList.size(); i++) { if (mDelList.get(i) == v) { curView = i; break; } } if (curView >= 0) { mAddList.remove(curView); mDelList.remove(curView); mLlContent.removeViewAt(curView); } } 删除就很简单了, 先弄清点击的是哪个按钮, 然后把相关的一股脑删了即可. 最后 其实这样改动视图还是比较过时的, 之后会准备一篇RecyclerView增删条目的文章. 到时候一对比就可以看到效果了. 但是在某些场合用用还是可以的, 比如弹窗中微调布局之类的. 喜欢记得点赞哦, 暗中关注我也是可以的~

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

语音科技圈新动态,亚马逊开放Alexa底层技术

考虑到未来最大的回报可能是来自电子商务领域的服务,亚马逊已经开始提供Alexa的独享优惠,以鼓励人们通过语音购物。 近日,为帮助开发者将Alexa的聊天功能融入他们自己的应用,让用户通过语音控制几乎所有的软件,亚马逊面向开发者开放了他们的Alexa的底层技术。 据悉,这项名为Amazon Lex的服务在去年年末就已经推出了预览版。亚马逊CTO维纳·沃格尔斯(Werner Vogels)表示,目前,亚马逊在语音识别和处理方面的能力已经足以支持用户更便捷的使用对话助手或聊天机器人了,不再像以前的工具那么繁琐难用。 将开放Alexa的底层技术作为一项服务,不仅可以通过数百万的用户,利用人们发送给应用的文本和录音来训练Lex以及Alexa,从而持续改进亚马逊的语音识别技术,还可以帮助亚马逊加快数据收集速度。 据统计,目前Echo等使用Alexa的设备销量大约为1000万台,可以预见,此次开放Alexa的底层技术,亚马逊很有可能成为语音控制计算领域的顶尖企业。 与其他云计算服务一样,亚马逊将根据Lex处理的文本和语音数量向开发者收取一定的费用。此外,考虑到未来最大的回报可能是来自电子商务领域的服务,亚马逊已经开始提供Alexa的独享优惠,以鼓励人们通过语音购物。 原文发布时间: 2017-04-20 14:28 本文作者: 伶轩 本文来自云栖社区合作伙伴镁客网,了解相关信息可以关注镁客网。

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

我的架构之路 — 配置中心(三)— 动态更新配置

包含两方面的含义:一、变化的配置能够下发到客户端.二、客户端能够方便地处理这些变化的配置。下面会讲普通监听器回调方式和spring 注解到field的方式。 配置下发 1)客户端间隔20秒(可配)去数据库拉取配置,sql传递的参数有配置名称、环境、上一次最大更新时间2)取到配置后,合并更新本地备份。3)通过监听器的方式通知配置变化。 #监听器接口 public interface ConfigUpdateListener { void update(Properties properties); } #启动时添加监听器 public void addConfigUpdateListener(ConfigUpdateListener configUpdateListener) { configUpdateListeners.add(configUpdateListener); } #配置变化,调用监听器进行通知 for (ConfigUpdateListener configUpdateListener : configUpdateListeners) { configUpdateListener.update(changedProperties); } spring 注解方式绑定成员变量 通过@ConfigValue注解来实现变量绑定,当配置变化的时候会同时更新这个变量。这种方式可以用于一起开关切换、降级处理的场景。 @ConfigValue("baseUrl") private String baseUrl; 实现原理:1)从配置中心获取配置。2)通过BeanPostProcessor 遍历每个spring bean,找出所有包含@ConfigValue注解的field,然后设置值为配置中心的属性值,同时把记录field到Map对象,以后更新配置时就不用想办法遍历了。这里有一个严格处理原则,如果配置中心找不到相应key或值赋值时候报异常,终止程序,保证安全性。其实代码对非spring的、static 成员变量也支持,只是需要程序启动时候指定包含这些static变量的类名列表。 public class PropertyPlaceholderConfigurer extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer implements BeanPostProcessor { private Map<String,List<BeanField>> configMap= new ConcurrentHashMap<String,List<BeanField>>(); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { ConfigInjectSupport.inject(mergedProperties,bean.getClass(),bean,configMap); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } public static void inject(Properties properties, Class clazz, Object bean, Map<String,List<BeanField>> configMap){ Field[] fields = clazz.getDeclaredFields(); if (null != fields) { for (Field f : fields) { // 如果 bean ==null(非spring),则必须是静态方法 if(bean==null && !Modifier.isStatic(f.getModifiers())) continue; ConfigValue configValue = f.getAnnotation(ConfigValue.class); if (configValue != null) { String key = configValue.value(); f.setAccessible(true); Object value = properties.get(key); if (value != null) { try { f.set(bean, converter.convertIfNecessary(value, f.getType(), f)); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }else{ RuntimeException e= new RuntimeException("can not find config. key="+key+", class="+clazz+", field="+f.getName()); e.printStackTrace(); throw e; } List<BeanField> list = configMap.get(key); if (list == null) { list = new ArrayList<BeanField>(); configMap.put(key, list); } BeanField beanField=new BeanField(); beanField.setBean(bean); beanField.setField(f); list.add(beanField); } } } clazz = clazz.getSuperclass(); } 3)加入监听器,接收变化的配置,更新field值 public static void addConfigUpdateListener(final Map<String,List<BeanField>> configMap) { DefaultConfigClient.addConfigUpdateListener(new ConfigUpdateListener() { @Override public void update(Properties properties) { for (Map.Entry<Object, Object> e : properties.entrySet()) { List<BeanField> beanFields = configMap.get(e.getKey().toString()); if (beanFields != null) { Object value = properties.get(e.getKey()); for (BeanField beanField : beanFields) { try { ConfigValue configValue = beanField.getField().getAnnotation(ConfigValue.class); if(configValue.updatable()) { ConfigInjectSupport.setFieldValue(beanField, value); } } catch (IllegalAccessException ex) { ex.printStackTrace(); } } } } } }); } public static void setFieldValue(BeanField beanField,Object value) throws IllegalAccessException { Field f=beanField.getField(); f.set(beanField.getBean(), ConvertUtils.convert(value,f.getType())); }

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

动态加载Js代码到Head标签中的脚本

我遇到了这样的问题,请教google,结果大多数只是介绍那个注册js的几个函数,而这几个函数插入的js都在body里面,幸而在老外那里看到了这个代码,其实比较简单,但够有用 1 HtmlGenericControlInclude2 = new HtmlGenericControl( " script " ); 2 Include2.Attributes.Add( " type " , " text/javascript " ); 3 Include2.InnerHtml = " alert('JavaScriptinPageHeader'); " ; 4 this .Page.Header.Controls.Add(Include2); 或 Literalli = new Literal(); li.Text = " <script</script> " ; this .Page.Header.Controls.Add(li); 或者 Code 欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处! 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/archive/2009/10/24/1589315.html ,如需转载请自行联系原作者

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

安全动态深解析:DDoS攻击的发展与演变

二十年来,分布式拒绝服务攻击(DDoS)一直是网络犯罪分子进行攻击的一个重要的工具,如今其感染蔓延得越来越广泛,功能也越来越强大。 什么是DDoS攻击? 分布式拒绝服务(DDoS)攻击是指攻击者或攻击者们试图使服务无法交付。这可以通过阻止任何访问的事物来实现:服务器,设备,服务,网络,应用程序,甚至应用程序内的特定事务。在DoS攻击中,它向系统发送恶意数据或请求,而DDoS攻击可以来自多个系统。 通常,这些攻击是通过请求数据来攻击淹没系统的。这可能是向Web服务器发送大量的请求来访问一个页面,而这个页面不能响应用这些需求而崩溃;或者可能是数据库遭遇大量查询,其结果是使可用的互联网带宽,CPU和内存容量变得不堪重负。 其影响范围可能是应用程序和网站体验服务的中断,甚至导致整个业务宕机。 DDoS攻击的症状 DDoS攻击看起来像许多可能产生可用性问题的非恶意事件,例如服务器或系统被破坏,合法用户的合法请求太多,甚至导致数据传输中断。它通常需要流量分析来确定正在发生的情况。 当今的DDoS攻击 然而,分布式拒绝服务攻击的危害让人们改变了对它的看法。2000年年初,加拿大高中生Michael Calce,网名为“黑手党男孩”,通过一个分布式拒绝服务(DDoS)攻击,设法关闭了当时全球最主要门户网站之一雅虎(Yahoo)网站的服务。在接下来的一周中,Calce又成功地中断了亚马逊,CNN和eBay等其他网站的服务。 当然不是这并不是DDoS攻击的第一次实施,但是这种高度公开和一系列成功的攻击将拒绝服务攻击从新奇和微小的骚扰转变成了首度信息安全官和首席信息官维护业务安全运营的噩梦。 从那时起,DDoS攻击已经成为一种频繁发生的威胁,因为它们作为网络活动的一种手段,通常用于目标明确的报复,进行敲诈勒索,甚至发动网络战。 经过多年的发展和演变,DDoS攻击的功能和危害也变得越来越大。20世纪90年代中期,每秒可能只有150次请求攻击,但这足以让许多系统瘫痪。如今他们传播的速度甚至超过1000Gbps。这在很大程度上是由现代僵尸网络的庞大规模所推动的。 去年秋天,互联网基础架构服务提供商Dyn DNS(如今的Oracle DYN)遭到数以千万计的IP地址的DNS查询服务的袭击,这是去年所发生的最新和最强大的DDoS攻击之一。据报道,通过物联网僵尸网络病毒“Mirai”实施的这起袭击事件感染了超过100,000个物联网设备,其中包括IP摄像机和打印机。在其爆发的高峰期,“Mirai”僵尸网络病毒感染了40万台以上的机器人。亚马逊,Netflix,Reddit,Spotify,Tumblr和Twitter等服务都遭到攻击。 “Mirai”僵尸网络的特点在于,与大多数DDoS攻击不同,它主要攻击安全防护比较脆弱的物联网设备,而不是电脑和服务器。根据调研机构BI Intelligence的调查,到2020年,将有340亿台互联网连接设备,而大多数(240亿台)将是物联网设备。 不幸的是,“Mirai”不会是最后一个物联网的僵尸网络。在Akamai,Cloudflare,Flashpoint,Google,RiskIQ和Cymru团队的安全团队进行的调查中,发现了一个同样规模大小的僵尸网络,被称之为WireX,这由100多个国家的10万个安全设备组成的僵尸网络。而这次调查是针对内容提供商和内容传送网络的一系列大型DDoS攻击所促成的。 DDoS攻击工具 通常,DDoS攻击者依赖于僵尸网络,这是集中控制的受到恶意软件感染的系统网络的集合。这些受感染的端点通常是计算机和服务器,但更多的是物联网设备和移动设备。攻击者通过网络钓鱼攻击,恶意攻击和其他大规模感染技术等手段识别和攻击脆弱的系统。攻击者通过各种方法越来越多地从构建者那里租用这些僵尸网络。 DDoS攻击的类型 DDoS攻击有三个主要类别:第一类是使用大量虚假流量来降低资源(如网站或服务器),包括ICMP,UDP和欺骗数据包泛洪攻击。第二类是DDoS攻击使用数据包来定位网络基础架构和基础架构管理工具。这些协议攻击包括SYN Floods和Smurf DDoS等。第三类是一些DDoS攻击针对组织的应用层,并通过恶意编写的请求来淹没应用程序。这三个类别的DDoS攻击目标是一致的:使网络资源反应迟钝或完全无反应。 DDoS攻击如何演变 如上所述,这些攻击通过租用的僵尸网络来实现变得越来越普遍。而这一趋势将会持续下去。 另一个趋势是在攻击中使用多个攻击向量,也称为高级持久拒绝服务(APDoS)。例如,APDoS攻击可能涉及应用层,例如对数据库和应用程序的攻击以及直接在服务器上的攻击。 “这超越了单纯的洪水攻击。”Binary Defense公司合伙人兼执行总监Chuck Mackey说。 另外,Mackey解释说,攻击者通常不仅直接针对受害者,还直接攻击受害者所依赖的组织,如互联网服务提供商和云计算提供商。他说:“这些是具有高影响力的广泛攻击,并且协调一致。” 这也正在改变DDoS攻击对组织的影响,并扩大了他们的风险。美国富理达律师事务所(Foley &Lardner LLP)的网络安全律师Mike Overly说:“企业不仅要关心自己免受DDoS攻击,还要关注其所依赖的广泛的业务合作伙伴,供应商和服务商是否会遭遇攻击。安全最古老的格言之一就是业务的安全与否取决于最薄弱环节。在当今的环境(最近的违规行为证明)中,最弱的环节可以就是第三方。” 当然,网络犯罪分子还在不断改进和完善DDoS攻击,其技术和策略也不会停滞不前。正如JASK公司安全研究总监Rod Soto所说,新增的物联网设备,机器学习和人工智能的兴起都将在这些攻击中发挥重要的作用。 “攻击者最终将这些技术整合到DDoS攻击中,使安全人员难以应对,特别是那些无法通过简单的ACL或签名来阻止的攻击。因此,DDoS攻击的安全防御技术也必须向这个方向发展。”Soto说。 本文转自d1net(转载)

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册