首页 文章 精选 留言 我的

精选列表

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

基于kubernetes构建Docker集群管理详解

一、环境部署 1、平台版本说明 1)Centos7.0 OS 2)Kubernetes V0.6.2 3)etcd version 0.4.6 4)Docker version 1.3.2 2、平台环境说明 192.168.1.20 kubernetes etcd 192.168.1.21 kubernetes docker 192.168.1.22 kubernetes docker 192.168.1.23 kubernetes docker 在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。 Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。 每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。 Kubernetes主要由以下几个核心组件组成: etcd保存了整个集群的状态; apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制; controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等; scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上; kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理; Container runtime负责镜像管理以及Pod和容器的真正运行(CRI); kube-proxy负责为Service提供cluster内部的服务发现和负载均衡; 3、环境安装 1)系统初始化工作(所有主机) 系统安装-选择[最小化安装] # yum -y install wget ntpdate bind-utils lrzsz vim # wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/epel-release-7-6.noarch.rpm # yum update CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙(熟悉度更高,非必须)。 1.1、关闭firewall: # systemctl stop firewalld.service #停止firewall # systemctl disable firewalld.service #禁止firewall开机启动 2 )安装Etcd Kubernetes(192.168.1.20主机) #yum install etcd kubernetes -y 3 )安装Kubernetes docker(192.168.1.21,192.168.1.22,192.168.1.23主机) #yum install kubernetes docker -y 4、启动服务 1) master 启动服务(192.168.1.20) #systemctl daemon-reload #systemctl enable kube-apiserver.service #systemctl start kube-apiserver.service #systemctl enable kube-controller-manager #systemctl start kube-controller-manager #systemctl enable kube-controller-manager #systemctl start kube-controller-manager ####通过systemctl status <service> 查看服务是否启动成功 此处修改过的配置文件 #cat /etc/kubernetes/config | grep -v ^# | grep -v ^$ KUBE_LOGTOSTDERR="--logtostderr=false"#设置为false表示将日志写入文件 KUBE_LOG_LEVEL="--v=2"#日志级别 KUBE_ALLOW_PRIV="--allow-privileged=false" #如果设置为true,则kubernetes将允许pod中运行拥有系统特权的容器应用 KUBE_MASTER="--master=http://192.168.1.20:8080" #cat /etc/kubernetes/apiserver | grep -v ^# | grep -v ^$ KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"#apiserver绑定主机的非安全ip地址 KUBE_API_PORT="--port=8080"#apiserver绑定主机的非安全端口号,默认8080 KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.1.20:2379" KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"#server地址段,不能与实际ip冲突 KUBE_ADMISSION_CONTROL="--admission- control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota" #kubernetes集群的准入控制设置 KUBE_API_ARGS="" 2) slave启动服务 (192.168.1.21,192.168.1.22,192.168.1.23) #systemctl daemon-reload #systemctl enable kubelet #systemctl start kubelet #systemctl enable kube-proxy #systemctl start kube-proxy #cat /etc/kubernetes/kubelet | grep -v ^# | grep -v ^$ KUBELET_ADDRESS="--address=127.0.0.1" KUBELET_HOSTNAME="--hostname-override=192.168.1.21"#master里获取的minion名字 KUBELET_API_SERVER="--api-servers=http://192.168.1.20:8080" KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/podinfrastructure:latest" KUBELET_ARGS="--logtostderr=true --log-dir=/var/log/kubernetes --v=2" 使用kubectl get nodes 查看已经加进来的node 本文转自 转身撞墙角 51CTO博客,原文链接:http://blog.51cto.com/chentianwang/1957398

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

【docker】基于Dockerfile构建monogdb服务镜像

YUM源创建的Dockerfile内容为: [root@docker1 Mongodb]# vi Dockerfile #设置从我们之前创建的sshd镜像继承 FROM sshd:centos MAINTAINER waitfish from dockerpool.com ADD mongodb-3.2.repo /etc/yum.repos.d/ RUN \ yum update -y && \ yum install -y mongodb-org && \ #这里不推荐使用yum安装monodb,实在下载速度太慢 yum clean all # 创建mongodb存放数据文件的文件夹 RUN mkdir -p /data/db VOLUME /data/db ENV AUTH yes # Add run scripts 添加脚本 ADD run.sh /run.sh ADD set_mongodb_password.sh /set_mongodb_password.sh RUN chmod 755 ./*.sh EXPOSE 27017 EXPOSE 28017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MongoDB是一款可扩展、高性能的开源文档(Document-Oriented)数据库。它采用C++开发,支持复杂的数据类型和强大的查询语言,提供了关系数据库的绝大部分功能。MongoDB由于其高性能、易部署、易使用等特点,已经在各种领域都得到了广泛的应用。 ① 下载文件 从GitHub Dockerpool社区账户下载Mongodb镜像项目: [root@docker1 ~]# git clone https://github.com/DockerPool/Mongodb.git Cloning into 'Mongodb'... remote: Counting objects: 12, done. remote: Compressing objects: 100% (10/10), done. remote: Total 12 (delta 2), reused 12 (delta 2), pack-reused 0 Unpacking objects: 100% (12/12), done. 查看内容,包括写好的Dockerfile和若干脚本等: [root@docker1 ~]# cd Mongodb/ [root@docker1 Mongodb]# ls Dockerfile mongodb-3.2.repo mongodb-linux-x86_64-rhel70-3.6.0.tgz pwgen-2.08.tar.gz run.sh set_mongodb_password.sh ② 其中Dockerfile内容为: [root@docker1 Mongodb]# cat Dockerfile #设置从我们之前创建的sshd镜像继承 FROM sshd:centos MAINTAINER waitfish from dockerpool.com COPY mongodb-linux-x86_64-rhel70-3.6.0.tgz /mongodb-linux-x86_64-rhel70-3.6.0.tgz COPY pwgen-2.08.tar.gz /pwgen-2.08.tar.gz RUN yum update -y && yum install -y gcc automake autoconf libtool make RUN tar -xf pwgen-2.08.tar.gz WORKDIR pwgen-2.08 RUN ./configure && make && make install #定义工作目录 WORKDIR / RUN tar -xf mongodb-linux-x86_64-rhel70-3.6.0.tgz RUN mv mongodb-linux-x86_64-rhel70-3.6.0 /usr/local/mongodb #设置环境变量 ENV PATH /usr/local/mongodb/bin:$PATH #删除压缩包 RUN rm -rf mongodb-linux-x86_64-rhel70-3.6.0.tgz pwgen-2.08.tar.gz # 创建mongodb存放数据文件的文件夹 RUN mkdir -p /data/db VOLUME /data/db ENV AUTH yes # Add run scripts 添加脚本 ADD run.sh /run.sh ADD set_mongodb_password.sh /set_mongodb_password.sh RUN chmod 755 ./*.sh EXPOSE 27017 EXPOSE 28017 CMD ["/run.sh"] ③ set_mongodb_password.sh脚本主要负责配置数据库的用户名和密码,内容为: [root@docker1 Mongodb]# cat set_mongodb_password.sh #这个脚本主要设置数据库的用户名和密码 #!/bin/bash #判断是否已经设置过密码 if [ -f /.mongodb_password_set ]; then echo "MongoDB password already set!" exit 0 fi /usr/local/mongodb/bin/mongod --smallfiles --nojournal & PASS=${MONGODB_PASS:-$(pwgen -s 12 1)} _word=$( [ ${MONGODB_PASS} ] && echo "preset" || echo "random" ) RET=1 while [[ RET -ne 0 ]]; do echo "=> Waiting for confirmation of MongoDB service startup" sleep 5 mongo admin --eval "help" >/dev/null 2>&1 RET=$? done #通过docker logs + id可以看到下面的输出 echo "=> Creating an admin user with a ${_word} password in MongoDB" mongo admin --eval "db.addUser({user: 'admin', pwd: '$PASS', roles: [ 'userAdminAnyDatabase', 'dbAdminAnyDatabase' ]});" mongo admin --eval "db.shutdownServer();" echo "=> Done!" touch /.mongodb_password_set echo "========================================================================" echo "You can now connect to this MongoDB server using:" echo "" echo " mongo admin -u admin -p $PASS --host <host> --port <port>" echo "" echo "Please remember to change the above password as soon as possible!" echo "========================================================================" ④ run.sh脚本是主要的启动脚本,内容为: [root@docker1 Mongodb]# cat run.sh #!/bin/bash if [ ! -f /.mongodb_password_set ]; then /set_mongodb_password.sh fi if [ "$AUTH" == "yes" ]; then export mongodb='/usr/local/mongodb/bin/mongod --nojournal --auth --httpinterface --rest' else export mongodb='/usr/local/mondodb/bin/mongod --nojournal --httpinterface --rest' fi if [ ! -f /data/db/mongod.lock ]; then eval $mongodb else export mongodb=$mongodb' --dbpath /data/db' rm /data/db/mongod.lock mongod --dbpath /data/db --repair && eval $mongodb fi ⑤ 创建镜像 根据Dockerfile创建镜像mongodb:latest: [root@docker1 Mongodb]# docker build -t mongodb . [root@docker1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mongodb latest adf9a26bb498 15 minutes ago 1.19 GB ...... ⑥ 使用示范: 启动后台容器,并分别映射27017,28017,22端口到本地: [root@docker1 Mongodb]# docker run -d -p 27017:27017 -p 28017:28017 -p 37017:22 mongodb b38f560ba2b16a4e0c9c5b77c02e2e07b9f45eed8ce7de5dd2d6755d8d962050 [root@docker1 Mongodb]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b38f560ba2b1 mongodb "/run.sh" 4 seconds ago Up 3 seconds 0.0.0.0:27017->27017/tcp, 0.0.0.0:28017->28017/tcp, 0.0.0.0:37017->22/tcp trusting_pasteur [root@docker1 Mongodb]# docker logs b38f560ba2b1 ...... ======================================================================== You can now connect to this MongoDB server using: mongo admin -u admin -p NQ1VmsSWUwF1 --host <host> --port <port> Please remember to change the above password as soon as possible! ======================================================================== ...... 输出中的 NQ1VmsSWUwF1 就是admin用户的密码 还可以利用环境变量在容器启动时指定密码: [root@docker1 Mongodb]# docker run -d -p 27017:27017 =p 37017:22 -e MONGODB_PASS="mypass" mongodb 甚至,设定不需要密码: [root@docker1 Mongodb]# docker run -d 27017:27017 -p 28017:28017 -e AUTH=no mongodb 同样,读者可以使用-v参数来映射本地目录到容器。 ⑦ 详细启动参数: Mongodb的启动参数有很多,包括: --quiet #安静输出 --port arg #指定服务端口号,默认端口27017 --bind_ip arg #绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP --logpath arg #指定Mongodb日志文件,注意是指定文件不是目录 --logappend #使用追加的方式写日志 --pidfilepath arg #PID File的完整路径,如果没有设置,则没有PID文件 --keyFile arg #集群的私钥的完整路径,只对于Replica Set架构有效 --unixSocketPrefix arg #UNIX域套接字替代目录,(默认为/tmp) --fork #以守护进程的方式运行MongoDB,创建服务器进程 --auth #启用验证 --cpu #定期显示CPU的利用率和iowait --dbpath arg #指定数据库路径 --dialog arg #diaglog选项 0=off 1=w 2=R 3=both 7=W+some reads --directoryperdb #设置每个数据库将被保存在一个单独的目录 --journal #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里 --journalOptions arg #启用日志诊断选项 --ipv6 #启用ipv6选项 --jsonp #允许JSONP形式通过HTTP访问(有安全影响) --maxConns args #最大同时连接默认2000 --noauth #不启用验证 --nohttpinterface #关闭http接口,默认关闭27018端口访问 --noprealloc #禁用数据文件预分配(往往影响性能) --noscripting #禁用脚本引擎 --notablescan #不允许表扫描 --noubixsocket #禁用Unix套接字监听 --nssize arg (=16) #设置信数据库.ns文件大小(MB) --objcheck #在收到客户数据,检查的有效性 --profile arg #档案参数 0=off 1=slow 2=all --quota #限制每个数据库的文件数,设置默认为8 --quotaFiles arg #number of filess allower per db, requires --quota --rest #开启简单的rest API --repair #修复所有数据库run repair on all dbs --repairpath arg #修复库生成的文件的目录,默认为目录名称dbpath --slowms arg (=100) #value of slow for profile and console log --smallfiles #使用较小的默认文件 --syncdelay arg (=60) #数据写入磁盘的时间秒数(0=never,不推荐) --sysinfo #打印一些诊断系统信息 --upgrade #如果需要升级数据库 * Replication 参数 --------------------------------------------------------------------------------------------------- --fastsync #从一个dbpath里启用从库复制服务,该dbpath的数据库是主库的快照,可用于快速启用同步 --autoresync #如果从库与主库同步数据差得多,自动重新同步 --oplogSize arg #设置oplog的大小(MB) * 主/从参数 --------------------------------------------------------------------------------------------------- --master #主库模式 --slave #从库模式 --source arg #从库 端口号 --only arg #指定单一的数据库复制 --slavedelay arg #设置从库同步主库的延迟时间 * Replica set(副本集)选项 -------------------------------------------------------------------------------------------------- --relSet arg #设置副本集名称 * Sharding(分片)选项 -------------------------------------------------------------------------------------------------- --configsvr #声明这是一个集群的config服务,默认端口为27019,默认目录/data/configdb --shardsvr #声明这是一个集群的分片,默认端口27018 --noMoveParanoia #关闭偏执为moveChunk数据保存 上述参数也可以直接在mongod.conf配置文件中配置,例如: dbpath = /data/mongodb logpath = /data/mongodb/mongodb.log logappend = true fork = true auth = true 本文转自 Mr_sheng 51CTO博客,原文链接:http://blog.51cto.com/sf1314/2048024

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

详解Dialog(二)——有关列表的构建

一、普通列表 普通列表的样式是这样的: 要实现这样的列表样式,是通过下面的方法来实现的: [java] view plain copy builder.setItems(CharSequence[]items,DialogInterface.OnClickListenerlistener) builder.setItems(intitemsId,DialogInterface.OnClickListenerlistener) 这两种方法实现的效果都是一样的, [java] view plain copy setItems(CharSequence[]items,DialogInterface.OnClickListenerlistener) 这个items传进去的是一个字符串数组; [java] view plain copy setItems(intitemsId,DialogInterface.OnClickListenerlistener) 这个传进去的一个itemsId,是在XML中定义好的一个字符串数组资源的ID; 下面,我们一个个看看他们的具体用法: 1、字符串数组 下面是上图是实现上图效果的代码: [java] view plain copy String[]mItems={"item0","item1","itme2","item3","itme4","item5","item6"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("使用列表字符串"); builder.setItems(mItems,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 可以看到首先构造一个mItems数组,然后在buidler.setItems直接传进去就好了。至于DialogInterface.OnClickListener(){}函数就是对点击事件的监听,which表示当前点击的是哪个ITEM的索引。 2、字符串资源ID 首先在xml文件夹下建一个字符串资源XML,命名为:array.xml,位置如图: 然后定义一段字符串数组: [java] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <resources> <string-arrayname="dialog_items"> <item>王菲</item> <item>王力宏</item> <item>帅哥</item> <item>美女</item> </string-array> </resources> 下面就是利用SetItem来生成列表了: [java] view plain copy AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("使用ResourceID"); builder.setItems(R.array.dialog_items,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 在这里的SetItems时直接将我们字符串数组的name直接设置进去,出来的效果就是这样的: 二、单选列表 单选列表的样式是这样的: 要实现单选列表,主要是通过下面四个其中之一来实现的: 方法一: [java] view plain copy setSingleChoiceItems(CharSequence[]items,intcheckedItem,DialogInterface.OnClickListenerlistener) 与上面一样,传进去一个字符串数组,和初始化时选中的ITEM,构造一个单选列表 方法二: [java] view plain copy setSingleChoiceItems(intitemsId,intcheckedItem,DialogInterface.OnClickListenerlistener) 同样,与上面的例子相同,这里传进去的是一个字符串数组的资源ID,字符串数组的构造方法与上面相同,就不再赘述 方法三: [java] view plain copy setSingleChoiceItems(ListAdapteradapter,intcheckedItem,DialogInterface.OnClickListenerlistener) 这 个方法是最难理解的方法,因为这里的ListAdapter并不能是普通的Adapter,不信你传一个Adapter,保证出来只是你自己的ITEM视 图,旁边的单选按钮却出不来,其实这里的Adapter只是重写单选按钮旁的文字的样式,并不支持所有的Adapter,这个我会在本文最后讲述。方法四: [java] view plain copy setSingleChoiceItems(Cursorcursor,intcheckedItem,StringlabelColumn,DialogInterface.OnClickListenerlistener) 这里通过传进去一个Cursor来构造对应的字符串数组,可以是数据库Cursor,也可以其它系统自带的数据Cursor,但基本上用不到,就不再讲了 好了,关于方法三,因为下面会接着讲SetAdapter的知识,所以这部分我留在最后再讲,这里先讲下方法一和方法二: 方法一和方法二,与上例没什么区别,下面我就以方法一以例来讲讲上面的效果图是怎么实现的吧: 代码如下: [java] view plain copy String[]mItems={"攻","受","全能型","不告诉你"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("你懂的"); builder.setSingleChoiceItems(mItems,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ //TODOAuto-generatedmethodstub Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 很简单,构造一个mItems的String字符串,然后直接传进去setSingleChoiceItems中,默认选中第一个,即索引是0的项。 三、多选列表 先看看效果图: 自带的多选构造函数有如下几个: 方法一: [java] view plain copy setMultiChoiceItems(CharSequence[]items,boolean[]checkedItems,DialogInterface.OnMultiChoiceClickListenerlistener) 一样,传进去一个ITEMS数组和对应的项目的选中与否状态的数组; 方法二: [java] view plain copy setMultiChoiceItems(intitemsId,boolean[]checkedItems,DialogInterface.OnMultiChoiceClickListenerlistener) 这里传进去的是一个字符串数组,与第一部分相同 方法三: [java] view plain copy setMultiChoiceItems(Cursorcursor,StringisCheckedColumn,StringlabelColumn,DialogInterface.OnMultiChoiceClickListenerlistener) 同样,这里传进去的是一个CURSOR,可以是数据库的指针,也可以是系统自带数据的指针,基本不怎么用,就不讲了 下面以方法一为例看看多选列表的构造过程: [java] view plain copy String[]mItems={"经常犯二","傻叉一枚","逗逼","小清纯","沉稳大叔","有时可爱"}; AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("性格类型"); builder.setMultiChoiceItems(mItems, newboolean[]{false,false,false,false,false,false,false}, newDialogInterface.OnMultiChoiceClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich,booleanisChecked){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } } ); builder.show(); 这里构造了两个数组,一个是字符串数组,另一个每项对应是否选中的boolean数组 [java] view plain copy String[]mItems={"经常犯二","傻叉一枚","逗逼","小清纯","沉稳大叔","有时可爱"}; 对应的选中项的布尔值数组: [java] view plain copy newboolean[]{false,false,false,false,false,false,false} 四、自定义列表项 这节我带大家自定义列表项的实现,故名思义,就是每个ITEM都是我们自己来定义,使用我们自己的Adapter,先看看效果: 要实现自定义列表主要是造下面这个函数来实现的: [java] view plain copy setAdapter(ListAdapteradapter,DialogInterface.OnClickListenerlistener) 直接将我们构造好的Adapter设置进去。 下面就带大家实现下图示中的视图: 1、构造Adapter 有关派生自BaseAdapter来构造ListViewAdapter的过程就不再细讲了,大家可以参考我以前的两篇文章: 1、《List控件使用---SimpleAdapter使用详解(一)》 2、《BaseAdapter——convertView回收机制与动态控件响应》 第 一篇现在看来着实太烂了,一直想重写又没时间来做,大家可以再搜搜网上的其它相关文章来学一下有关BaseAdapter的相关内容吧。第二篇有关 convertView的回收机制写的还是挺不错的,大家可以仔细看看,相信会对ListView的机制有一个更清晰的理解。废话不多说了,下面言转正 转,看看我们这里的ListAdapter的构造过程: 首先是单个Item的布局:(list_item.xml) 很简单,采用水平布局,左边一个图像,右边一个对应的TEXT,这里只是基本实现功能,大家完全可以在理解这篇文章的基础上派生出更复杂的视图 [java] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent"> <ImageView android:id="@+id/item_imageview" android:layout_width="80dip" android:layout_height="80dip" android:scaleType="fitCenter"/> <TextView android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical|left" android:textSize="20sp"/> </LinearLayout> 对应的视图类: [java] view plain copy privateclassViewHolder{ publicTextViewmTvTitle; publicImageViewmImageView; } 其中有两个变量,一个存储对应的TextView,另一个存储对应的ImageView; 现在我们还需要一个类来存储视图类中TextView的标题字符串,和对应ImageView的图片资源的ID值,这就是我们的数据类: [java] view plain copy publicstaticclassDataHolder{ publicStringtitle; publicintImageID; publicDataHolder(Stringtitle,intimageID){ this.title=title; this.ImageID=imageID; } } 我们先阶段性的看看我们的ListViewAdapter: 首先是派生自BaseAdapter,然后是构造函数,我们传进去一个DataHolder的列表,用来存储每个Item应该显示的内容 [java] view plain copy publicclassListItemAdapterextendsBaseAdapter{ privateList<DataHolder>mDataList=newArrayList<DataHolder>(); privateLayoutInflatermInflater; publicListItemAdapter(Contextcontext,ArrayList<DataHolder>datalist){ if(datalist!=null&&datalist.size()>0){ mDataList.addAll(datalist); } mInflater=LayoutInflater.from(context); } ……………… } 然后是最关键的getView部分: [java] view plain copy publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.list_item,null); holder.mTvTitle=(TextView)convertView.findViewById(R.id.item_text); holder.mImageView=(ImageView)convertView.findViewById(R.id.item_imageview); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); returnconvertView; } 首先是通过covertView的tag来获取重复利用的convertView,这什么要这么写,看《BaseAdapter——convertView回收机制与动态控件响应》 然后是利用传进来的数据,初始化列表Item: [java] view plain copy holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); 最后返回convertView,让系统去做绘图 到这里ListViewAdapter的构造过程就基本完成了,下面是完整的代码: [java] view plain copy /** *Createdbyharvic *date2015-1-11 **/ publicclassListItemAdapterextendsBaseAdapter{ privateList<DataHolder>mDataList=newArrayList<DataHolder>(); privateLayoutInflatermInflater; publicListItemAdapter(Contextcontext,ArrayList<DataHolder>datalist){ if(datalist!=null&&datalist.size()>0){ mDataList.addAll(datalist); } mInflater=LayoutInflater.from(context); } @Override publicintgetCount(){ returnmDataList.size(); } @Override publicObjectgetItem(intposition){ returnmDataList.get(position); } @Override publiclonggetItemId(intposition){ returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.list_item,null); holder.mTvTitle=(TextView)convertView.findViewById(R.id.item_text); holder.mImageView=(ImageView)convertView.findViewById(R.id.item_imageview); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mImageView.setImageResource(mDataList.get(position).ImageID); holder.mTvTitle.setText(mDataList.get(position).title); returnconvertView; } privateclassViewHolder{ publicTextViewmTvTitle; publicImageViewmImageView; } publicstaticclassDataHolder{ publicStringtitle; publicintImageID; publicDataHolder(Stringtitle,intimageID){ this.title=title; this.ImageID=imageID; } } } 2、构造列表 在MainActivity中,首先是初始化我们的ListViewAdapter,要初始化Adapter,就要首先传进去一个DataHolder的数组,所有要先构造一个DataHolder的数组 [java] view plain copy privateArrayList<ListItemAdapter.DataHolder>initDataHolder(){ ArrayList<ListItemAdapter.DataHolder>datalist=newArrayList<ListItemAdapter.DataHolder>(); ListItemAdapter.DataHolderdata_1=newListItemAdapter.DataHolder("可爱萌宠1",R.drawable.animal1); ListItemAdapter.DataHolderdata_2=newListItemAdapter.DataHolder("可爱萌宠2",R.drawable.animal2); ListItemAdapter.DataHolderdata_3=newListItemAdapter.DataHolder("可爱萌宠3",R.drawable.animal3); ListItemAdapter.DataHolderdata_4=newListItemAdapter.DataHolder("可爱萌宠4",R.drawable.animal4); datalist.add(data_1); datalist.add(data_2); datalist.add(data_3); datalist.add(data_4); returndatalist; } 在构造完成数据列表之后,下面就是构造我们的自定义的列表了,我把整个对话框显示过程整合成了一个函数createCustomList,代码如下: [java] view plain copy privatevoidcreateCustomList(){ ArrayList<ListItemAdapter.DataHolder>dataHolders=initDataHolder(); ListItemAdapteradapter=newListItemAdapter(MyActivity.this,dataHolders); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setAdapter(adapter,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); } OK啦,到这,整个自列表项的内容就讲完了,下面再回过来给大家说说上面我们提到的有关单选列表自定义Adapter的问题。 五、有关单选列表自定义Adapter 这里主要讲的函数是第二部分单选列表中的方法三: [java] view plain copy setSingleChoiceItems(ListAdapteradapter,intcheckedItem,DialogInterface.OnClickListenerlistener) 在第四部分,我们构造了一个ListAdapter,这里需要的也是同样的一个ListAdapter,那我们直接将第四部分中的Adapter传进去,会是什么效果呢? 也就是利用下面的代码: 我们直接在createCustomList()上面改一下,即把builder.setAdapter()直接换成setSingleChoiceItems() ,传进去Adpter,看看在我们定义的视图后面会不会出现一个单选按钮呢? [java] view plain copy privatevoidcreateCustomList(){ ArrayList<ListItemAdapter.DataHolder>dataHolders=initDataHolder(); ListItemAdapteradapter=newListItemAdapter(MyActivity.this,dataHolders); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setSingleChoiceItems(adapter,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); } 运行一下,效果是这样的: 看见了没,毛也没有,坑爹玩意,那这个函数到底是用来做什么的呢,在源码中有这样一个文件: 地址在:$android_sdk_home/platforms/Android-x.x/data/res/layout/simple_list_item_single_choice.xml 文件内容是这样的: [html] view plain copy <CheckedTextViewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/single_list_item" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" /> 利用这个玩意是可以实现效果的,我们来试一下。 1、新建Adapter 新建一个布局文件,来保存ListVIew的每项的Item,代码如下: [html] view plain copy <CheckedTextViewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/single_list_item" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" /> 在Adapter中,同样,用来保存ITEM视图的ViewHolder类,如下: [java] view plain copy privateclassViewHolder{ publicTextViewmName; } 因 为在布局中只有一个TextView,所以在ViewHolder中也只需要一个TextView与其对应,至于类似上面的承载对应数据的 DataHolder,因为我们只需要一个String字符串数组就足够了,所以就没必要再新建一个类来承载这些数据了,所以我们要构造Adapter 时,传进来一个字符串数组就好了: 所以简单的构造函数为: 在构造时,传进来我们每项要显示的标题的字符串数组String[] items,并将其直接添加到我们的List<String> mList中。 [java] view plain copy publicclassSingleChoiceAdapterextendsBaseAdapter{ privateLayoutInflatermInflater; privateList<String>mList=newArrayList<String>(); publicSingleChoiceAdapter(Contextcontext,String[]items){ mInflater=LayoutInflater.from(context); if(items==null||items.length<=0){ return; } for(Stringitem:items){ mList.add(item); } } ………… } 然后是最关键的getView()部分: [java] view plain copy publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.single_choice_item,null); holder.mName=(TextView)convertView.findViewById(R.id.single_list_item); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mName.setText(mList.get(position)); returnconvertView; } 这段代码难度不大,就是每次绘图时,将TextView的内容设置为我们指定的字符串: [java] view plain copy holder.mName.setText(mList.get(position)); 下面是SingleChoiceAdapter完整的代码: [java] view plain copy /** *Createdbyharvic *date2015-1-11 */ publicclassSingleChoiceAdapterextendsBaseAdapter{ privateLayoutInflatermInflater; privateList<String>mList=newArrayList<String>(); publicSingleChoiceAdapter(Contextcontext,String[]items){ mInflater=LayoutInflater.from(context); if(items==null||items.length<=0){ return; } for(Stringitem:items){ mList.add(item); } } @Override publicintgetCount(){ returnmList.size(); } @Override publicObjectgetItem(intposition){ returnmList.get(position); } @Override publiclonggetItemId(intposition){ returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupviewGroup){ ViewHolderholder=null; if(convertView==null){ holder=newViewHolder(); convertView=mInflater.inflate(R.layout.single_choice_item,null); holder.mName=(TextView)convertView.findViewById(R.id.single_list_item); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mName.setText(mList.get(position)); returnconvertView; } privateclassViewHolder{ publicTextViewmName; } } 然后就是使用的阶段了 2、构造单选列表 这里首先构造SingleChoiceAdapter的实例,然后将其传入setSingleChoiceItems中,代码如下: [java] view plain copy String[]mItems={"攻","受","全能型","不告诉你"}; SingleChoiceAdapteradapter=newSingleChoiceAdapter(MyActivity.this,mItems); AlertDialog.Builderbuilder=newAlertDialog.Builder(MyActivity.this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("可爱萌宠"); builder.setSingleChoiceItems(adapter,0,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialogInterface,intwhich){ Toast.makeText(MyActivity.this,"clicked:"+which,Toast.LENGTH_LONG).show(); } }); builder.create(); builder.show(); 运行出来的效果如图: 看到没,这里效果是出来了,可见,在单选按钮中,定义Adapter并不是随便定义的,只能定义CheckedTextView的视图,其它是不支持的!!!! 好了,到这里本篇就结束了,下篇给大家讲讲有关自定义对话框的内容。 本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5434828.html,如需转载请自行联系原作者

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

如何构建AI驱动型智能服务?

人工智能(简称AI)驱动型智能服务将把当下各类前沿技术(例如区块链)、物联网以及客户体验因素结合起来——而其未来的发展方向则必然以信任协调为基础。 机器学习、深度学习、自然语言处理以及认知计算的结合将彻底改变人类与机器之间的交互方式。AI驱动型智能服务将学会感知人类身处的周遭环境、根据其以往行动推断个人喜好,并巧妙地通过日常生活对人类加以引导。事实上,对于此类目标的追求将成为当下十年乃至未来最为重要的转变,并使得AI驱动型智能服务被引入各个行业以及各类业务流程当中。 对于企业而言,AI驱动型智能服务则将深刻影响未来的工作流、物联网服务、客户体验以及同步分类帐(即区块链技术)。业务的成功将以AI处理结果为前提(详见图一)。一旦结果建立完成,企业即可规划AI驱动型智能服务,并利用其以规模化方式实现编排、自动化与民主化个性体验交付。 七类AI成果 AI的颠覆性能力源自其速度、精确性以及强化人类判断的能力。我们可以通过以下七类成果了解AI项目所能够实现的具体价值: 1.感知并描述当前正在发生的事态。第一类成果能够同以往的手动编程方案一样描述周遭背景。 2.向你通知你所需了解的情况。通知内容可通过警报、工作流、提醒器以及其它信号加以呈现,并经由手动输入及学习等方式交付额外信息。 3.提供行动建议。根据以往行动提供建议,同时利用权重属性、决策管理以及机器学习随时间推移进行建议修订。 4.自动执行重复工作。随着机器学习不断发展成熟,自动化的实用性也将更上一层楼。 5.提供预测以启发合理预期。要进行预测,我们首先需要建立起深度学习与神经网络,并利用其对行为进行预测与测试。 6.预防负面结果。利用认知推理机制发现潜在威胁。 7.态势感知提供当前重要信息。态势感知将进一步模拟人类在制定决策方面的能力。 AI驱动型智能服务的实现,必须以信任为基础 由于AI驱动型智能服务必须将决策制定责任指派给各原子驱动智能服务,因此任何AI驱动型智能服务的实现基础皆为信任。下面,我们将探讨AI驱动型智能服务信任协调体系中的五大关键组成部分。 1.配合AI,利用数据化足迹与数据产出建立匿名与显式资料。每一个人、设备或者网络都会提供部分信息。这种数字化足迹或产出可能源自面部分析、网络IP地址甚至是步态采集。利用AI与认知推理,系统将能够分析其中的模式并将其与身份关联起来。这意味着AI服务将可在不同情景之下识别并认出对应个人。 2.渲染式体验使交互更为自然。情景、内容、协作与频道共同成为AI驱动型服务交付渲染式独特体验的基础。这类服务将利用地理位置、时间段、天气、心跳率甚至是个人感受等因素作为情景属性,同时结合服务自身所掌握的对象身份与偏好,旨在改进相关性交交付更适合的内容。感知与响应机制将通过对话与文本框的形式实现参与者同机器间的协作。频道则包括各类具体交互点,例如移动、社交、信息亭以及个人等等。其目标在于根据身份提供自然的用户体验。 3.大规模个性化数字服务交付。以规模化方式实现预测分析、催化条件以及选择。预测分析允许客户获得提前预判的能力。催化条件则负责响应的交付或者触发。每位个人或设备都将拥有自己的情景体验,具体取决于身份、历史偏好以及当前需求。从自行选择到情景驱动型选择,再到多选择变量测试,AI系统将令选择拥有更为理想的满意度水平。 4.价值交换成就信任协调。采取行动之后,价值交换即可以交易方式进行。货币、非货币与共识是三种常见的价值交换形式。虽然货币交换也许最为人们所熟知,但非货币价值交换(包括认同、访问与影响)通常也能够带来令人瞩目的价值形式。另外,简单的一致性协商或者协议也能够在患者治疗方案或者土地所有权归属等层面实现价值交换。 5.步调与反馈值得关注,AI支持型机器学习亦然。在机器学习与其它AI工具的支持之下,智能服务开始考虑交付的步调问题:一次性、临时、重复、基于订阅以及阈值驱动型机制皆在其中。利用机器学习技术,系统将了解到智能服务的具体交付方式,并将其运用于未来的交互当中。 总结陈词:AI带来的强化效果 担心机器人统治世界确实有些多虑。事实上,成功的AI驱动型智能服务将强化人类智能——正如机器强化人类的物理体能一样。AI驱动型智能服务在定义同步分类帐技术(即区块链)、物联网、客户体验以及未来工作方式的商业模式当中扮演着关键性角色。由此实现的错误率降低、决策速度提升、需求信号识别、结果预测以及“灾难”预防等能力也必将得到越来越多人们的认可。 原文发布时间为:2017年9月7日 本文作者:杨昀煦 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

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

用户登录
用户注册