首页 文章 精选 留言 我的

精选列表

搜索[笔记工具],共10000篇文章
优秀的个人博客,低调大师

openstack学习笔记:Kvm基础实验环境

系统:centos7.1 安装环境:桌面环境、kvm基础服务 一、关闭selinux 1 2 [root@localhost~] #setenforce0 [root@localhost~] #sed-i's/enforcing/disabled/g'/etc/selinux/config 二、关闭iptables 1 2 [root@localhost~] #systemctlstopfirewalld [root@localhost~] #systemctldisablefirewalld 三、确认服务器cpu是否支持虚拟化 1 2 3 4 5 6 7 8 9 [root@localhost~] #grep-o'vmx\|svm'/proc/cpuinf vmx vmx vmx vmx vmx vmx vmx vmx 四、安装桌面 1、已经安装的软件以及可以安装的软件 2、安装图形桌面 1 [root@localhost~] #yum-ygroupinstall"XWindowSystem""GNOMEDesktop" 3、安装vncserver 1 [root@localhost~] #yum-yinstalltigervnc-server 4、配置vnc 1 2 3 4 5 6 7 8 9 10 [root@localhost~] #vncserver Youwillrequireapasswordtoaccessyourdesktops. Password: Verify: xauth: file /root/ .Xauthoritydoesnotexist New 'localhost.localdomain:1(root)' desktopislocalhost.localdomain:1 Creatingdefaultstartupscript /root/ .vnc /xstartup Startingapplicationsspecified in /root/ .vnc /xstartup Log file is /root/ .vnc /localhost .localdomain:1.log 5、使用vnc连接测试 五、安装kvm 1、安装kvm依赖包 1 2 3 4 [root@localhost~] #yum-yinstallqemu-kvmlibvirtvirt-installbridge-utilsvirt-manager [root@localhost~] #lsmod|grep kvmkvm_intel1480810 kvm4611261kvm_intel 2、启动libvirt服务 1 2 [root@localhost~] #systemctlstartlibvirtd [root@localhost~] #systemctlenablelibvirtd 这样就可以创建kvm虚拟机了 本文转自 wangpengtai 51CTO博客,原文链接:http://blog.51cto.com/wangpengtai/1953235,如需转载请自行联系原作者

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

OpenStack(Kilo版本)基础架构学习笔记

一、OpenStack项目简介 OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。 OpenStack项目是一个开源的云计算平台,支持所有类型的云环境。项目的目标是提供实施简单、可扩展性强、标准统一的云计算管理平台。 通常作为一个基础设施即服务(IAAS)解决方案,OpenStack开源云操作系统中心控制大量的计算、存储和网络资源。通过管理员授权用户通过WEB界面提供资源管理,各个服务之间的通过API通信,各个模块之间通过消息队列通信。 图1.1. OpenStack免费云操作系统 下面表格列出了OpenStack服务列表。 表1.1. OpenStack服务列表 二、OpenStack历史版本 OpenStack的每个主版本系列以字母表顺序(A~Z)命名,以年份及当年内的排序做版本号,从第一版的Austin(2010.1)到目前最新的稳定版Kilo(2015.1),共经历了11个主版本。而版本Liberty和Mitaka正在开发中。 三、OpenStack概念架构 下面图是OpenStack官方提供的OpenStack架构图。该架构由OpenStack网络,可选的块存储和面向对象存储服务器组成的三个节点的架构组成。 图1.2. OpenStack架构图 架构示例: OpenStack Neutron网络的示例架构,至少需要下面三个节点: 1)控制节点(Controller node)运行身份认证服务,镜像服务,管理部分计算和网络服务,运行网络插件以及仪表板。它还包括一些支持服务,例如 SQL 数据库、消息队列和网络时间协议(NTP)。 2)网络节点(Network node)运行 Networking 插件和一些代理,并提供switching、routing、NAT 和 DHCP 服务。这个节点还处理外部(Internet) 租户虚拟机实例的连接。 3)计算节点(Compute node)运行hypervisor 管理程序,Compute 使用 KVM 作为默认的hypervisor。计算节点也可以运行Networking 插件和代理,它们连接租户网络到虚拟机上并提供防火墙(security groups) 服务。 四、OpenStack Networking(neutron)架构最小硬件配置。 图1.3. OpenStack Neutron架构最小硬件配置 五、OpenStack Networking(neutron)架构网络配置 图1.4. OpenStack Neutron架构网络配置 六、OpenStack Networking(neutron)架构服务部署 图1.5. OpenStack Neutron架构服务配置 备注: 1)OpenStack官方文档: http://docs.openstack.org/kilo/install-guide/install/apt/content/ 2)OpenStack历史版本: https://wiki.openstack.org/wiki/Releases 3)本博客测试的版本都是OpenStack Kilo版本。 本文转自 sfzhang 51CTO博客,原文链接:http://blog.51cto.com/sfzhang88/1688452,如需转载请自行联系原作者

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

Android开发学习笔记:圆角的Button

在res目录下的drawable-mdpi建立xml文件shape.xml,如下图所示: shape.xml <?xmlversion="1.0"encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!--填充的颜色--> <solidandroid:color="#FFFFFF"/> <!--设置按钮的四个角为弧形--> <!--android:radius弧形的半径--> <cornersandroid:radius="5dip"/> <!--padding:Button里面的文字与Button边界的间隔--> <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" /> </shape> main.xml 在android:background="@drawable/shape"就使用了shape.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/hello" /> <Button android:id="@+id/roundButton" android:text="圆角按钮" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/shape" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,RoundButtonDemoActivity!</string> <stringname="app_name">RoundButtonDemo</string> </resources> RoundButtonDemoActivity.java packagecom.android.RoundButtonDemo.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.Toast; publicclassRoundButtonDemoActivityextendsActivity{ ButtonroundButton; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); roundButton=(Button)findViewById(R.id.roundButton); //使用匿名类注册Button事件 roundButton.setOnClickListener(newOnClickListener() { publicvoidonClick(Viewv) { Toast.makeText(RoundButtonDemoActivity.this,"你点击了圆角按钮",Toast.LENGTH_LONG).show(); } }); } } 效果图: 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/630051

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

Android开发学习笔记:浅谈Content Provider

一.Content Provider的概念介绍 Content Providers是所有应用程序之间数据存储和检索的桥梁,它使得各个应用程序之间实现数据共享。是应用程序间共享数据的唯一途径。Content Provider 主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。其中包括添加,删除,查询,更新等操作。 在Content Provider使用过程中,还需要借用ContentResolver对象间接来操作ContentProvider来获取数据。ContentResolver通过应用程序的getContentResolver()方法获得。一般情况下,ContentResolver是单实例的,但是可以有多个ContentResolver在不用的应用程序和不同的进程之间和ContentResolver交互。 二.Content Provider的简介 1.Content Provider的常用方法 //查询 query(Uri,String[],String,String[],String); //插入 insert(Uri,ContentValues); //更新 update(Uri,ContentValues,String,String[]); //删除 delete(Uri,String,String[]); //获得MIME数据类型 getType(Uri); 2.数据模型 Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。 _ID NUMBER NUMBER_KEY LABEL NAME TYPE 13 (425) 555 6677 425 555 6677 Kirklandoffice Bully Pulpit TYPE_WORK 44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME 45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE 53 201.555.4433 201 555 4433 Love Nest Rex Cars TYPE_HOME 3.URI URI,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(data set)的URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。Content Provider就是通过URI对象来共享其数据的。 URI的格式图如下: 各个部分的组成: A:标准前缀,是固定的,"content://"是用来标识数据是由Content Provider管理的 schema。 B:URI的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在 元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称 C:需要访问的数据字段名称。 D:如果URI中包含表示需要获取的记录的_ID;如何有D部分,则就返回该_ID对应的数据,否则表示返回整张表的数据 三.Content Provider实例 Anroid系统自带的Content Provider对象 获得系统联系人信息(姓名和手机号码)的例子 MainActivity.java packagecom.lingdududu.provide; importandroid.app.Activity; importandroid.os.Bundle; importandroid.provider.ContactsContract; importandroid.provider.ContactsContract.PhoneLookup; importandroid.database.Cursor; importandroid.graphics.Color; importandroid.widget.TextView; importandroid.content.ContentResolver; publicclassMainActivityextendsActivity{ publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); TextViewtv=newTextView(this); Stringstring=getQueryData(); //设置文本的颜色 tv.setTextColor(Color.BLUE); //设置TextView显示的内容 tv.setText(string); //设置文本字体的大小 tv.setTextSize(30.0f); //显示到屏幕 setContentView(tv); } publicStringgetQueryData(){ Stringstring=""; //得到ContentResolver对象 ContentResolvercr=getContentResolver(); //取得电话本中开始一项的光标 Cursorcursor=cr.query(ContactsContract.Contacts.CONTENT_URI,null, null,null,null); //向下移动光标 while(cursor.moveToNext()){ //取得联系人名字 intnameFieldColumnIndex=cursor .getColumnIndex(PhoneLookup.DISPLAY_NAME); Stringcontact=cursor.getString(nameFieldColumnIndex); //取得电话号码 StringContactId=cursor.getString(cursor .getColumnIndex(ContactsContract.Contacts._ID)); Cursorphone=cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=" +ContactId,null,null); while(phone.moveToNext()){ StringPhoneNumber=phone .getString(phone .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); string+=(contact+":"+PhoneNumber+"\n"); } } cursor.close(); returnstring; } } 注意:记得在AndroidManifest.xml加上17行的权限声明 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.lingdududu.provide" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <uses-permissionandroid:name="android.permission.READ_CONTACTS"/> </manifest> 通讯录中联系人的信息: 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/667264

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

Android开发学习笔记:Activity的简介

1.Activity的概念介绍 Activity是Android组件中最基本也是最常用的一种组件,在一个Android应用中,一个Activity通常就是一个单独的屏幕。每一个Activity都被实现为一个独立的类,并且继承于Activity这个基类。 activity类处于android.app包中,继承体系如下: 1.java.lang.Object 2.android.content.Context 3.android.app.ApplicationContext 4.android.app.Activity 2.Activity的创建 Activity提供了和用户交互的可视化界面。创建一个Activity一般是继承Activity(也可以是LisActivity,MapActivity等),覆盖Activity的onCreate( )方法,在该方法中调用setContentView( )方法来展示要显示的视图,调用findViewById( )方法实例化组件。注意Activity只有在清单文件中声明才能使用。 3.Activity的应用实例 3.1两个Activity之间的切换 要做到两个Activity之间的切换(也就是从一个Activity启动另一个Activity),可以使用startActivity( )方法或者startActivityForResult( ) (能够返回结果)。这两个方法要传递的参数是组件Intent。 下面的实例是MainActivity和SecondActivity之间的切换: 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" /> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转到SecondActivity" /> </LinearLayout> second.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/hello2" /> <Button android:id="@+id/secondBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回" /> </LinearLayout> MainActivity.java packagecom.android.test.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.btn); //响应按钮btn事件 btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //显示方式声明Intent,直接启动SecondActivity Intentit=newIntent(MainActivity.this,SecondActivity.class); //启动Activity startActivity(it); } }); } } SecondActivity.java packagecom.android.test.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassSecondActivityextendsActivity{ privateButtonsecondBtn; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.second); secondBtn=(Button)findViewById(R.id.secondBtn); //响应按钮secondBtn事件 secondBtn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //显示方式声明Intent,直接启动MainActivity Intentintent=newIntent(SecondActivity.this,MainActivity.class); //启动Activity startActivity(intent); } }); } } AndroidManifest.xml清单文件,16~18行为SecondActivity在清单文件里的声明 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SecondActivity" android:label="@string/app_name"> </activity> </application> </manifest> 效果图: 3.2.Activity之间传递数据 在Android开发中不同的Activity之间要传递数据,就需要用到对象Bundle,讲要传递的信息封装在该对象里面,并通过Intent对象传递到另一个Intent中。 下面的实例在MainActivity中输入用户名数据,并将该用户名传递给SecondActivity: 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/hello" /> <EditText android:id="@+id/txt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入用户名" /> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确定" /> </LinearLayout> second.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:id="@+id/secondTxt" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">MainActivity</string> <stringname="app_name">ActivityDemo</string> <stringname="app_name1">SecondActivity</string> </resources> MainActivity.java packagecom.android.test.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.EditText; publicclassMainActivityextendsActivity{ privateButtonbtn; privateEditTexttxt; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.btn); txt=(EditText)findViewById(R.id.txt); //响应按钮btn事件 btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //获得用户名字符串 StringuseName=txt.getText().toString(); //声明Bundle对象 Bundledata=newBundle(); //讲用户名信息添加到Bundle data.putString("useName",useName); //显示方式声明Intent,直接启动SecondActivity Intentit=newIntent(MainActivity.this,SecondActivity.class); //为Intent添加Bundle it.putExtras(data); //启动Activity startActivity(it); } }); } } SecondActivity.java packagecom.android.test.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.widget.TextView; publicclassSecondActivityextendsActivity{ privateTextViewsecondTxt; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.second); //获得Intent Intentit=getIntent(); //从Intent中获得Bundle对象 Bundlebundle=it.getExtras(); //从Bundle中获得那么 Stringname=bundle.getString("useName"); secondTxt=(TextView)findViewById(R.id.secondTxt); secondTxt.setText(name); } } AndroidManifest.xml清单文件 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SecondActivity" android:label="@string/app_name1"> </activity> </application> </manifest> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/636587

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

特殊权限-SUID,SGID,Sticky 学习笔记

SUID : 运行某程序时,相应进程的属主是程序文件自身的属主,而不是启动者 chmod u+s FILENAME (添加 SUID 权限) chmod u-s FILENAME (除去SUID 权限) 如果 FILE 本身原来就有执行权限,则 SUID 显示为 s ; 否则显示 S; passwd 命令默认具有 SUID 权限 SGID :运行某程序时,相应进程的属组是程序文件自身的属组,而不是启动者 (目录有SGID权限后,在该目录下创建文件目录时,创建后的属组为目录自身的属组,) chmod g+s FILENAME (添加 SGID 权限) chmod g-s FILENAME (除去 SGID 权限) Sticky : 在一个公共目录,每个用户都可以创建文件,删除自己的文件,但不能删除别人的文件 chmod o+t DIR (添加 Sticky 权限) chmod o-t DIR (删除 Sticky 权限) 权限表示 SUID : 4 SGID : 2 Sticky : 1 chmod 1755 /tmp/test #test具有 755 权限 ( 1 : 具有 Sticky 权限 ) chmod 3755 /tmp/test #test具有 755 权限 ( 2 : 具有 SGID 权限 + 1 : 具有 Sticky 权限 ) chmod 5755 /tmp/test #test具有 755 权限 ( 4 : 具有 SUID 权限 + 1 : 具有 Sticky 权限 ) SUID : 实例测试 让一个普通用户对指定文件具有原本没有的查看权限 (user1用户可以查看 /etc/shadow 文件) 1 2 3 4 5 6 7 8 9 10 11 12 13 [root@nono~] #useradduser1#添加用户user1 [root@nono~] #passwduser1 [root@nono~] #ls-l/etc/shadow#查看/etc/shadow文件,权限为000,所以除root用户都不能查看 ----------.1rootroot10537月309:54 /etc/shadow [root@nono~] #su-user1#切换到user1用户,应为/etc/ [user1@nono~]$ cat /etc/shadow #user1用户没有权限查看 cat : /etc/shadow :权限不够 [root@beiyong2~] #chmodu+s/bin/cat#将/bin/cat命令添加SUID命令,则cat命令的执行者为文件自身的属主,而不是启动者 [root@beiyong2~] #ls-l/bin/cat#SUID命令添加成功(若/bin/cat本身就有执行权限,添加SUID命令后,显示为s否则为S) -rwsr-xr-x.1rootroot4856810月152014 /bin/cat [user1@beiyong2~]$ cat /etc/shadow #user1可以查看 bin:*:15980:0:99999:7::: daemon:*:15980:0:99999:7::: SGID : 实例测试 三个用户可以在同一目录中,创建文件目录,并互相修改文件内容 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 [user1@beiyong2~]$ tail -5 /etc/passwd #当前系统中有三个用户 user1:x:500:500:: /home/user1 : /bin/bash hbase:x:501:501:: /home/hbase : /bin/bash hadoop:x:502:502:: /home/hadoop : /bin/bash [root@beiyong2tmp] #mkdirproject#在/tmp目录中创建新目录/project [root@beiyong2tmp] #groupadddevelopteam#添加developteam用户组 [root@beiyong2tmp] #chown-R:developteam/tmp/project#将/tmp/project目录的属组改为developteam [root@beiyong2tmp] #ls-ldproject drwxr-xr-x.2rootdevelopteam40967月902:15project [root@beiyong2tmp] #usermod-a-Gdevelopteamuser1#分别将三个用户的附加组改为developteam [root@beiyong2tmp] #usermod-a-Gdevelopteamhadoop [root@beiyong2tmp] #usermod-a-Gdevelopteamhbase [root@beiyong2project] #ls-ld#查看project目录的权限,属组没有写权限,则添加 drwxr-xr-x.2rootdevelopteam40967月902:15. [root@beiyong2project] #chmodg+w/tmp/project [root@beiyong2project] #ls-ld drwxrwxr-x.2rootdevelopteam40967月902:15. [root@beiyong2project] #ll#分别用三个账号在/tmp/project目录中创建文件(a.*),没有权限编辑其他人的文件 -rw-rw-r--.1hadoophadoop07月902:33a.hadoop -rw-rw-r--.1hbasehbase07月902:34a.hbase -rw-rw-r--.1user1user107月902:33a.user1 [root@beiyong2~] #chmodg+s/tmp/project#给/tmp/project目录添加SGID权限 [root@beiyong2~] #ls-ld/tmp/project drwxrwsr-x.2rootdevelopteam40967月902:34 /tmp/project [root@beiyong2project] #ll#添加SGID权限后,用三个用户分别在/tmp/project目录下创建文件(b.*) 总用量0 -rw-rw-r--.1hadoophadoop07月902:33a.hadoop -rw-rw-r--.1hbasehbase07月902:34a.hbase -rw-rw-r--.1user1user107月902:33a.user1 -rw-rw-r--.1hadoopdevelopteam07月902:37b.hadoop -rw-rw-r--.1hbasedevelopteam07月902:37b.hbase -rw-rw-r--.1user1developteam07月902:37b.user1 三个用户创建的文件,属组均为developteam,故可以互相编辑删除对方文件 Sticky : 实例测试 同一目录下用户可以创建文件并互相修改,但不能删除对方的文件 1 2 3 4 5 [root@beiyong2project] #chmodo+t/tmp/project#给/tmp/project添加Sticky权限,(原有执行权限t,否则T) [root@beiyong2project] #ls-ld drwxrwsr-t.2rootdevelopteam40967月902:42. [hadoop@beiyong2project]$ rm -rfa.hbase #用hadoop用户身份去删除hbase用户的文件,删除失败(只能删除自己的文件目录) rm :无法删除 "a.hbase" :不允许的操作 完毕~~~ 本文转自 mlwzby 51CTO博客,原文链接:http://blog.51cto.com/aby028/1814364

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

Android学习笔记--SQLite使用方法

SQLite介绍 http://www.sqlite.org 官方网站 小型关系数据库 SQLiteOpenHelper使用方法 getReadableDatabase() getWritableDatabase() onCreate(SQLiteDatabasedb) onOpen(SQLiteDatabasedb) onUpgrade(SQLiteDatabsedb,intoldVersion,intnewVersion) Close(); //DatabaseHelper所为一个访问SQLite的助手类,提供两个方面的功能 //第一,getReadableDatabase()和getWritableDatabasr()可以获得SQLiteDatabase对象 //第二,提供onCreate和onUpgrade两个回调函数,允许我们在创建和升级数据库时,进行操作 例:publicclassDatabaseHelperextendsSQLiteOpenHelper{ //数据库版本号 PrivatestaticfinalintVERSION=1; //必须的构造函数 PublicDatabaseHelper(Contextcontext,Stringname,CursorFactoryfactory,intversion){ Super(context,name,factory,version); } PublicDatabaseHelper(Contextcontext,Stringname,intversion){ Super(context,name,null,version); } PublicDatabaseHelper(Contextcontext,Stringname){ Super(context,name,null,VERSION); } PublicvoidonCreate(SQLiteDatabasedb){ System.out.println("createadatabase"); Db.execSQL("createtableuser(idint,namevarchar(20))"); } PublicvoidonUpgrade(SQLiteDatabasedb){ System.out.println("updateadatabase"); } } 对SQLite的增删查改 Activity操作数据库例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象(调用DatabaseHelper) //创建一个数据库 PublicvoidonClick(Viewv){ //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db"); SQLiteDatabasedb=dbHelper.getReadableDatabase();//此时才会创建一个数据库 } //修改一个数据库 PublicvoidonClick(Viewv){ //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db",2);//版本号变了 SQLiteDatabasedb=dbHelper.getReadableDatabase(); } //插入操作 PublicvoidonClick(Viewv){ //生成ContentValues对象 ContentValuesvalues=newContentValues(); //key是列名,value是值,值必须对应数据库列数据类型 Values.put("id",1); Values.put("name","zhangsan"); //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db"); //得到可写数据库 SQLiteDatabasedb=dbHelper.getWritableDatabase(); //1.表名2,不允许空列3,值 Db.insert("user",null,values); } //更新操作 PublicvoidonClick(Viewv){ //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db"); //得到可写数据库 SQLiteDatabasedb=dbHelper.getWritableDatabase(); //1.表名2,不允许空列3,值 //生成ContentValues对象 ContentValuesvalues=newContentValues(); //key是列名,value是值,值必须对应数据库列数据类型 Values.put("name","zhangsanfeng"); //1.表名2.值,3,where子句(不包括where)4,为占位符赋值 Db.update("user",values,"id=?",newString[]{"1"}); } //查询数据库 PublicvoidonClick(Viewv){ //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db");//版本号变了 SQLiteDatabasedb=dbHelper.getReadableDatabase(); //1,表名2所要查询的列名3,筛选器4,筛选器值5.groupby6.having //7orderby创建游标对象读取数据 Cursorcursor=db.query("user","newString[]{"id","name"}","id=?") While(cursor.moveToNext()){ Stringname=cursor.getString(cursor.getColumnIndex("name")); System.out.println("query--->"+name); } } //删除操作 PublicvoidonClick(Viewv){ //当前的activity,还有数据名 DatabaseHelperdbHelper=newDatabaseHelper(SQLiteActivity.this,"test_db"); //得到可写数据库 SQLiteDatabasedb=dbHelper.getWritableDatabase(); //1.表名2.值,3,where子句(不包括where)4,为占位符赋值 Db.delete("user",values,"id=?",newString[]{"1"}); } 使用adb访问SQLite(linux命令行调试)abdshell=>ls-i=>cddata=>创建了数据库之后=>报名.数据库名=>即可进入该SQLite SQLite语句.schema//查看所有表 Linux知识补习:cd目录(进入目录)ls(查看当前目录) 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360571,如需转载请自行联系原作者

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

Android 经典笔记之八:CountDownTimer解读

目录介绍 CountDownTimer(倒计时计数器) 1.1 介绍 1.2 参数 1.3 公共方法 1.4 使用方法 1.5 源码分析 1.6 synchronized 关键字 0.本人写的综合案例案例说明及截图模块:新闻,音乐,视频,图片,唐诗宋词,快递,天气,记事本,阅读器等等接口:七牛,阿里云,天行,干货集中营,极速数据,追书神器等等 1.1介绍:定时执行在一段时间后停止的倒计时,在倒计时执行过程中会在固定间隔时间得到通知。1.2参数:millisInFuture 从开始调用start()到倒计时完成并onFinish()方法被调用的毫秒数。(倒计时时间,单位毫秒)countDownInterval 接收onTick(long)回调的间隔时间。(单位毫秒)1.3公共方法 public final void cancel ()取消倒计时(取消后,再次启动会重新开始倒计时) public abstract void onFinish ()倒计时完成时被调用 public abstract void onTick (long millisUntilFinished)固定间隔被调用 参数 millisUntilFinished 倒计时剩余时间。 public synchronized final CountDownTimer start ()启动倒计时 1.4使用方法 CountDownTimer timer = new CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { } public void onFinish() { Intent intent = new Intent(GuideActivity.this, TimerReceiver.class); intent.setAction("timer"); } }.start(); 源码分析 基本结构如下所示: CountDownTimer 这个类的基本结构(红色标明的为关键处,蓝色标明的为抽象函数,我们使用时必须进行实现) 功能实现的关键部分在于 mHandler,下面我们来看一看 mHandler 的源码: // handles counting down private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { synchronized (CountDownTimer.this) { if (mCancelled) { return; } final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else if (millisLeft < mCountdownInterval) { // no tick, just delay until done sendMessageDelayed(obtainMessage(MSG), millisLeft); } else { long lastTickStart = SystemClock.elapsedRealtime(); onTick(millisLeft); // take into account user's onTick taking time to execute long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); // special case: user's onTick took more than interval to // complete, skip to next interval while (delay < 0) delay += mCountdownInterval; sendMessageDelayed(obtainMessage(MSG), delay); } } } }; 主要在处理对 millisLeft 剩余时间的判断,其中 delay 的处理需要注意,当 onTick() 方法耗时过长时会进行跳过,可以用如下的流程图来表示整个流程: synchronized 关键字 值得注意的是,源码中 cancle(), start() 函数被 synchronized 修饰,mHandler.handleMessage(Message msg) 中代码段也被 synchronized 修饰,它主要是用来保证在同一时刻,至多只有一个线程执行该段代码 主要有以下两个特点: 当有一个线程访问某具体对象的一个被 synchronized 修饰的代码区域时,其它线程对该具体对象中所有被 synchronized 修饰的代码区域的访问都会被阻塞。 当有一个线程访问某具体对象的一个被 synchronized 修饰的代码区域时,其它线程对该具体对象中没有被 synchronized 修饰的代码区域的访问仍会正常进行。 其他说明 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts 领英:https://www.linkedin.com/in/chong-yang-049216146/ 简书:http://www.jianshu.com/u/b7b2c6ed9284 csdn:http://my.csdn.net/m0_37700275 网易博客:http://yangchong211.blog.163.com/ 新浪博客:http://blog.sina.com.cn/786041010yc github:https://github.com/yangchong211 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/ 脉脉:yc930211 360图书馆:http://www.360doc.com/myfiles.aspx 开源中国:https://my.oschina.net/zbj1618/blog 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1 邮箱:yangchong211@163.com 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100239.headeruserinfo.3.dT4bcV

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

Android Bitmap和Canvas学习笔记 [转]

原文:http://www.cnblogs.com/feisky/archive/2010/01/10/1643460.html 位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的。 1. 从资源中获取位图 可以使用BitmapDrawable或者BitmapFactory来获取资源中的位图。 当然,首先需要获取资源: Resources res=getResources(); 使用BitmapDrawable获取位图 使用BitmapDrawable (InputStream is)构造一个BitmapDrawable; 使用BitmapDrawable类的getBitmap()获取得到位图; // 读取InputStream并得到位图 InputStream is=res.openRawResource(R.drawable.pic180); BitmapDrawable bmpDraw=new BitmapDrawable(is); Bitmap bmp=bmpDraw.getBitmap(); 或者采用下面的方式: BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.pic180); Bitmap bmp=bmpDraw.getBitmap(); 使用BitmapFactory获取位图 (Creates Bitmap objects from various sources, including files, streams, and byte-arrays.) 使用BitmapFactory类decodeStream(InputStream is)解码位图资源,获取位图。 Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic180); BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来获取位图。 以上方法在编程的时候可以自由选择,在Android SDK中说明可以支持的图片格式如下:png (preferred), jpg (acceptable), gif (discouraged),和bmp(Android SDK Support Media Format)。 2. 获取位图的信息 要获取位图信息,比如位图大小、像素、density、透明度、颜色格式等,获取得到Bitmap就迎刃而解了,这些信息在Bitmap的手册中,这里只是辅助说明以下2点: 在Bitmap中对RGB颜色格式使用Bitmap.Config定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,缺少了一些其他的,比如说RGB_555,在开发中可能需要注意这个小问题; Bitmap还提供了compress()接口来压缩图片,不过AndroidSAK只支持PNG、JPG格式的压缩;其他格式的需要Android开发人员自己补充了。 3. 显示位图 显示位图可以使用核心类Canvas,通过Canvas类的drawBirmap()显示位图,或者借助于BitmapDrawable来将Bitmap绘制到Canvas。当然,也可以通过BitmapDrawable将位图显示到View中。 转换为BitmapDrawable对象显示位图 // 获取位图 Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic180); // 转换为BitmapDrawable对象 BitmapDrawable bmpDraw=newBitmapDrawable(bmp); // 显示位图 ImageView iv2 = (ImageView)findViewById(R.id.ImageView02); iv2.setImageDrawable(bmpDraw); 使用Canvas类显示位图 这儿采用一个继承自View的子类Panel,在子类的OnDraw中显示 public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new Panel(this)); } class Panel extends View{ public Panel(Context context) { super(context); } public void onDraw(Canvas canvas){ Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180); canvas.drawColor(Color.BLACK); canvas.drawBitmap(bmp, 10, 10, null); } } } 4. 位图缩放 (1)将一个位图按照需求重画一遍,画后的位图就是我们需要的了,与位图的显示几乎一样:drawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint)。 (2)在原有位图的基础上,缩放原位图,创建一个新的位图:CreateBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) (3)借助Canvas的scale(float sx, float sy) (Preconcat the current matrix with the specified scale.),不过要注意此时整个画布都缩放了。 (4)借助Matrix: Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180); Matrix matrix=new Matrix(); matrix.postScale(0.2f, 0.2f); Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(), bmp.getHeight(),matrix,true); canvas.drawColor(Color.BLACK); canvas.drawBitmap(dstbmp, 10, 10, null); 5. 位图旋转 同样,位图的旋转也可以借助Matrix或者Canvas来实现。 Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180); Matrix matrix=new Matrix(); matrix.postScale(0.8f, 0.8f); matrix.postRotate(45); Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(), bmp.getHeight(),matrix,true); canvas.drawColor(Color.BLACK); canvas.drawBitmap(dstbmp, 10, 10, null); 旋转效果: 6.图片水印的生成方法 生成水印的过程。其实分为三个环节:第一,载入原始图片;第二,载入水印图片;第三,保存新的图片。 /** * create thebitmapfrom a byte array * * @param src thebitmapobject you want proecss * @param watermark the water mark above the src * @return return abitmapobject ,if paramter's length is 0,return null */ privateBitmap createBitmap( Bitmap src, Bitmap watermark ) { String tag ="createBitmap"; Log.d( tag,"create a newbitmap"); if( src ==null) { returnnull; } intw = src.getWidth(); inth = src.getHeight(); intww = watermark.getWidth(); intwh = watermark.getHeight(); //create the new blankbitmap Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图 Canvas cv =newCanvas( newb ); //draw src into cv.drawBitmap( src,0,0,null);//在 0,0坐标开始画入src //draw watermark into cv.drawBitmap( watermark, w - ww +5, h - wh +5,null);//在src的右下角画入水印 //save all clip cv.save( Canvas.ALL_SAVE_FLAG );//保存 //store cv.restore();//存储 returnnewb; } 7.Canvas的save和restore onDraw方法会传入一个Canvas对象,它是你用来绘制控件视觉界面的画布。 在onDraw方法里,我们经常会看到调用save和restore方法,它们到底是干什么用的呢? save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。 save和restore要配对使用(restore可以比save少,但不能多),如果restore调用次数比save多,会引发Error。save和restore之间,往往夹杂的是对Canvas的特殊操作。 例如:我们先想在画布上绘制一个右向的三角箭头,当然,我们可以直接绘制,另外,我们也可以先把画布旋转90°,画一个向上的箭头,然后再旋转回来(这种旋转操作对于画圆周上的标记非常有用)。然后,我们想在右下角有个20像素的圆,那么,onDraw中的核心代码是: int px = getMeasuredWidth(); int py = getMeasuredWidth(); // Draw background canvas.drawRect(0, 0, px, py, backgroundPaint); canvas.save(); canvas.rotate(90, px/2, py/2); // Draw up arrow canvas.drawLine(px / 2, 0, 0, py / 2, linePaint); canvas.drawLine(px / 2, 0, px, py / 2, linePaint); canvas.drawLine(px / 2, 0, px / 2, py, linePaint); canvas.restore(); // Draw circle canvas.drawCircle(px - 10, py - 10, 10, linePaint); 效果如图1所示: 如果我们不调用save和restore会是什么样子呢?如图2所示: 从这两个图中,我们就能看到圆圈位置的明显差异。不进行Canvas的save和restore操作的话,所有的图像都是在画布旋转90°后的画布上绘制的。当执行完onDraw方法,系统自动将画布恢复回来。save和restore操作执行的时机不同,就能造成绘制的图形不同。 本文参考: Android SDK moandroid.com http://www.cnblogs.com/xirihanlin/archive/2009/07/24/1530246.html 本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/p/3582003.html,如需转载请自行联系原作者

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

Android 经典笔记七 全局弹窗Dialog

目录介绍 1.全局弹窗分析 2.全局弹窗必要条件 3.全局弹窗实现方式3.1. 利用系统弹出dialog 3.2. 获取WindowManager,直接添加view3.3. 在服务里,获取栈顶的Activity,弹窗 4.Dialog实现全局Loading加载框4.1. 自定义Loading类 4.2. 给自定义的Dialog添加自定义属性4.3. Loading布局4.4. 开始使用 5.遇到的问题5.1. 权限问题 5.2. Unable to add window 6.其他说明 0.本人写的综合案例案例说明及截图模块:新闻,音乐,视频,图片,唐诗宋词,快递,天气,记事本,阅读器等等接口:七牛,阿里云,天行,干货集中营,极速数据,追书神器等等 1.全局弹窗分析开始认为dialog需要依附在Activity上,后经查询可采取悬浮窗的模式,使其不必依附于Activity,可在任一页面弹出 2.全局弹窗必要条件 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);设置dialog的类型 清单文件配置:<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 3.全局弹窗实现方式 第一个方法利用系统弹出dialog 在alter.show()语句前加入: alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 然后在AndroidManifest.xml中加入权限:android.permission.SYSTEM_ALERT_WINDOW 第二个方法是获取WindowManager,直接添加view wmParams = new WindowManager.LayoutParams(); //获取的是WindowManagerImpl.CompatModeWrapper mWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE); //设置window type wmParams.type = LayoutParams.TYPE_PHONE; //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作) wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; //调整悬浮窗显示的停靠位置为左侧置顶 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 以屏幕左上角为原点,设置x、y初始值,相对于gravity wmParams.x = 0; wmParams.y = 0; //设置悬浮窗口长宽数据 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; LayoutInflater inflater = LayoutInflater.from(getApplication()); //获取浮动窗口视图所在布局 mFloatLayout = (LinearLayout) inflater.inflate(R.layout.float_layout, null); //添加mFloatLayout mWindowManager.addView(mFloatLayout, wmParams); 在服务里,获取栈顶的Activity,弹窗 public static void showActivityDialog(final Activity activity){ if(AppUtils.isActivityLiving(activity)){ int appCount = BaseApplication.getInstance().getAppCount(); Log.e("全局弹窗","------"); //只有当APP处于前台时才弹窗 if(appCount==1){ Log.e("全局弹窗","前台"); AlertDialog.Builder builder = new AlertDialog.Builder(activity); final AlertDialog alertDialog = builder.create(); alertDialog.setCancelable(false); View view = LayoutInflater.from(activity).inflate(R.layout.dialog_custom_view, null); alertDialog.setView(view); if(alertDialog.getWindow()!=null){ Window window = alertDialog.getWindow(); window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); window.setBackgroundDrawableResource(R.color.transparent); WindowManager.LayoutParams params = window.getAttributes(); //WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.width = WindowManager.LayoutParams.MATCH_PARENT; params.height = WindowManager.LayoutParams.MATCH_PARENT; params.gravity = Gravity.CENTER; window.setAttributes(params); //window.setGravity(Gravity.CENTER); //此处可以设置dialog显示的位置 //window.setWindowAnimations(R.style.dialog_custom_view); //添加动画 } //报错:Unable to add window -- token null is not for an application //全局弹窗必须依附Activity,必须在Activity运行下才能弹窗,否则崩溃 //注意,小米,三星等手机需要手动打开权限才行 if (Build.VERSION.SDK_INT >= 23) { if(!Settings.canDrawOverlays(activity)) { ToastUtils.showToast(activity,"请打开投资界允许权限开关"); Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(intent); return; } else { //Android6.0以上 if (!alertDialog.isShowing()) { alertDialog.show(); } } } else { //Android6.0以下,不用动态声明权限 if (!alertDialog.isShowing()) { alertDialog.show(); } } alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_BACK){ if(alertDialog.isShowing()){ alertDialog.dismiss(); } } return false; } }); AppUtils.setBackgroundAlpha(activity,0.5f); //Unable to add window android.view.ViewRootImpl$W@12b82d6 -- permission denied for this window type //alertDialog.show(); alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { AppUtils.setBackgroundAlpha(activity,1.0f); } }); } } } 4.Dialog实现全局Loading加载框 给自定义的Dialog添加自定义属性 Loading布局 开始使用 自定义Loading public abstract class ViewLoading extends Dialog { public abstract void loadCancel(); public ViewLoading(Context context) { super(context, R.style.Loading); // 加载布局 setContentView(R.layout.dialog_toast_view); ImageView progressImageView = (ImageView) findViewById(R.id.iv_image); //创建旋转动画 Animation animation =new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(2000); animation.setRepeatCount(10);//动画的重复次数 animation.setFillAfter(true);//设置为true,动画转化结束后被应用 progressImageView.startAnimation(animation);//开始动画 // 设置Dialog参数 Window window = getWindow(); if(window!=null){ WindowManager.LayoutParams params = window.getAttributes(); params.gravity = Gravity.CENTER; window.setAttributes(params); } } // 封装Dialog消失的回调 @Override public void onBackPressed() { //回调 loadCancel(); //关闭Loading dismiss(); } } 给自定义的Dialog添加自定义属性 <style name="Loading" parent="@android:style/Theme.Dialog"> <item name="android:windowFrame">@null</item> <item name="android:windowIsFloating">true</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> <!-- 设置背景色 透明--> <item name="android:background">@android:color/transparent</item> <item name="android:windowBackground">@android:color/transparent</item> <!-- 设置是否显示背景 --> <item name="android:backgroundDimEnabled">true</item> <!-- 设置背景透明度 --> <item name="android:backgroundDimAmount">0.6</item> <!-- 设置点击空白不消失 --> <item name="android:windowCloseOnTouchOutside">false</item> </style> 开始使用 // 添加Loading mLoading = new ViewLoading(this) { @Override public void loadCancel() { //loadCancle()是按返回键,Loading框关闭的回调,可以做取消加载请求的操作。 } }; // 显示Loading mLoading.show(); // 关闭Loading mLoading.dismiss(); 5.遇到的问题 权限问题 注意,由于有些手机(如小米)限制了悬浮窗口功能,默认不能显示,需要进入系统设置->其他应用管理, 找到你的应用,进入应用详情,启用悬浮窗功能。开启这个功能之后才能显示。 //注意,小米,三星等手机需要手动打开权限才行 if (Build.VERSION.SDK_INT >= 23) { if(!Settings.canDrawOverlays(activity)) { ToastUtils.showToast(activity,"请打开投资界允许权限开关"); Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(intent); return; } else { //Android6.0以上 if (!alertDialog.isShowing()) { alertDialog.show(); } } } else { //Android6.0以下,不用动态声明权限 if (!alertDialog.isShowing()) { alertDialog.show(); } } Unable to add window 原因分析 该异常表示view没有添加到窗口管理器,通常是我们dismiss对话框的时候,activity已经不存在了,建议不要在非UI线程操作对话框。 解决方案 [解决方案]:Dialog&AlertDialog,WindowManager不能正确使用时,经常会报出该异常,原因比较多,几个常见的场景如下: 1.上一个页面没有destroy的时候,之前的Activity已经接收到了广播。如果此时之前的Activity进行UI层面的操作处理,就会造成crash。UI层面的刷新,一定要注意时机,建议使用set_result来代替广播的形式进行刷新操作,避免使用广播的方式,代码不直观且容易出错。 2.Dialog在Actitivty退出后弹出。在Dialog调用show方法进行显示时,必须要有一个Activity作为窗口的载体,如果Activity被销毁,那么导致Dialog的窗口载体找不到。建议在Dialog调用show方法之前先判断Activity是否已经被销毁。 3.Service&Application弹出对话框或WindowManager添加view时,没有设置window type为TYPE_SYSTEM_ALERT。需要在调用dialog.show()方法前添加dialog.getWindow().SetType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)。 4.6.0的系统上, (非定制 rom 行为)若没有给予悬浮窗权限, 会弹出该问题, 可以通过Settings.canDrawOverlays来判断是否有该权限. 5.某些不稳定的MIUI系统bug引起的权限问题,系统把Toast也当成了系统级弹窗,android6.0的系统Dialog弹窗需要用户手动授权,若果app没有加入SYSTEM_ALERT_WINDOW权限就会报这个错。需要加入给app加系统Dialog弹窗权限,并动态申请权限,不满足第一条会出现没权限闪退,不满足第二条会出现没有Toast的情况。 建议 1.不要在非UI线程中使用对话框创建,显示和取消对话框; 2.尽量少用单独线程,出发是真正的耗时操作采用线程,线程也不要直接用Java式的匿名线程,除非是那种单纯的操作,操作完成不需要做其他事情的。 3.如果是在fragment中发起异步网络的回调中进行dialog的操作,那么在操作之前,需要判断 isAdd( ),避免fragment被回收了但是还要求dialog去dismiss 4.在Activity onDestroy中对Dialog提前进行关闭 6.其他说明 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts 领英:https://www.linkedin.com/in/chong-yang-049216146/ 简书:http://www.jianshu.com/u/b7b2c6ed9284 csdn:http://my.csdn.net/m0_37700275 网易博客:http://yangchong211.blog.163.com/ 新浪博客:http://blog.sina.com.cn/786041010yc github:https://github.com/yangchong211 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/ 脉脉:yc930211 360图书馆:http://www.360doc.com/myfiles.aspx 开源中国:https://my.oschina.net/zbj1618/blog 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1 邮箱:yangchong211@163.com 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100239.headeruserinfo.3.dT4bcV

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

安卓开发笔记——探索EventBus

1、关于EventBus: 组件通讯在Android开发中是不可避免的,随着业务需求的复杂化,代码中需要我们去处理的业务逻辑难度也不断增大。例如多个Fragment之间的数据传递,Service与Activity、Fragment之间的通讯,BroadCast与Activity、Fragment之间的通讯,各种startActivityForResult的使用,繁杂的操作令我们所厌倦,在GitHub上找了下解决方案,发现了一个不错的开源库EventBus,相信很多做过Android开发的朋友都或多或少对此有所了解。 EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。 这是EventBus在GitHub上的开源库地址:https://github.com/greenrobot/EventBus EventBus的大体关系是这样的:订阅者(Subscriber)通过订阅事件(Event)到总线,事件发布者(Publisher)发布事件(Event)到总线被订阅者(Subscriber)接收,其实说白了就是软件设计模式里的观察者模式。EventBus在使用的时候就是在合适的地方发布一个事件,使得注册了该事件接收的对象就可以收到通知,进行相应的操作。 2、初探EventBus: 文绉绉的文字描述令人厌烦,直接上代码说话吧,先来看下要实现的效果: 看似很简单的效果,点击按钮跳转界面,利用Intent发送一个消息,然后TextView接收显示。这是传统上的做法,如果真是这样做,那么写这篇文章的就完全没意义了。其实这里就是利用到了EventBus,并没有用到Intent来传递消息。 先来看下具体的代码(记得添加EventBus的引用),然后我再分部来解析: MainActivity.java SecondActivity.java MyEvent 上面的代码很简单,这里只是抛砖引玉并不做太多复杂的操作,大家可以根据自己的项目需求来添加对应的代码。 3、解析代码: 1、注册EventBus: 在添加EventBus的引用后,我们就可以对任意类进行注册绑定和解绑EventBus事件,注册方法和反注册方法很简单,在上面的代码中就可以看出来了,分别是register和unregister,这里的EventBus.getDefault是获取到EventBus实例的意思(单例)。 1 //注册绑定EventBus 2 EventBus.getDefault().register(this); 3 //解绑EventBus 4 EventBus.getDefault().unregister(this); 2、EventBus事件: EventBus很灵活,它对事件不进行任何的限制,也不需要继承或者实现任何类或者接口,可以是任意类型的实体类,好比上面代码提到的MyEvent。 3、EventBus事件发布者: 有了事件之后,我们就可以对事件进行发布,然后可以被订阅这个事件的所有订阅者所接收。发送事件很简单,有两种方法post与postSticky: 1 //立即发送事件 2 EventBus.getDefault().post(Object event); 3 //延迟发送事件 4 EventBus.getDefault().postSticky(Objet event); 4、EventBus事件订阅者: EventBus的事件订阅者可以是任何已经进行注册EventBus的类,订阅者的数量是没有上限的(很重要,下文会提到),这里的订阅有4种方法,这里都是由onEvent开头的,有着一定的区别: 1、onEvent: 如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。 2、onEventMainThread: 如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。 3、onEventBackground: 如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。 4、onEventAsync: 使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync。 1 public void onEvent(Object event) {} 2 public void onEventMainThread(Object event) {} 3 public void onEventBackgroundThread(Object event) {} 4 public void onEventAsync(Object event) {} 介绍完EventBus里的所有角色后,我们来理一理订阅/被订阅流程: 首先,要想成为事件订阅者需要先对EventBus进行注册绑定,然后在本类需要去写一个以onEvent开头的方法来接收处理消息事件,再来我们需要一个自定义的事件可以让事件的发布者发布,让事件的订阅者接收。事件的发布可以通过post方法或者是postSticky方法发布。 4、EventBus所带来的一些方便之处: EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。这是我们在文章开头所介绍过的,这里就不多说了,说几个在实际开发中所运用到的地方。 例如: 1、当某个页面的某些值发生变化的时候,需要去同时去更改多个页面相对应的值,这时候只要这些类注册订阅了该事件,那么我们就可以很轻松通过post发送消息来进行通讯。 2、某些时候,我们并不希望发布出来的Event立即被消费掉,而是等到时机成熟。比如说,在一个详情页点赞之后,产生一个事件,这个事件并不立即被消费,而是等用户退出详情页回到商品列表之后,接收到该事件,然后刷新Adapter等。其实这就是之前我们用startActivityForResult和onActivityResult做的事情。这里我们就可以利用postSticky来实现这样的机制。 总之,EventBus极大的减轻了我们各种组件之间的通讯复杂度,也大大减少了使用ActivityForResult的麻烦。真实值得极力推荐。 5、理解EventBus 从源码中我们可以知道,当我们在类中注册绑定EventBus的时候,它会去扫描当前类并记录下所有已onEvent开头的方法,存放在一个Map<Key,Value>中,在事件通过post发布之后,EventBus会根据post中实参的类型,去Map中查找对应的方法,并找到了对应的Thread,最终利用Java的反射机制去执行我们的方法。 onEventMainThread表示这个方法会在UI主线程执行。 onEventPostThread表示这个方法会在当前发布事件的线程中执行。 BackgroundThread表示如果在非UI主线程发布的事件,则直接执行,和发布在同一个线程中。如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用。 Async加入后台任务队列,使用线程池调用,注意没有BackgroundThread中的一个接一个。 作者:佚名 来源:51CTO

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

Spark源码阅读笔记一——part of core

内部accumulator通过心跳报告给drivertask运行时可以累加accumulator,但是不能读取value,value只能在driver获取spark内部用一个weakhashmap保存accumulator,便于gc的清理 CacheManagerspark的类用于负责传递RDD的分区内容给BlockManager,并保证一个节点不会载入一个rdd的两份拷贝,这个通过一个hashset实现,已载入的rdd会将id保存到set中获取和计算rdd时,先判断是否已经计算,如果没有再从blockmanager获取block然后计算结果。除非是本地模式,不然rdd的计算结果都会缓存如果rdd不需要在内存中缓存,则直接将计算结果通过iterator直接传给blockmanager在rdd需要缓存时,我们必须小心不能在内存中一次性展开全部的partition,否则如果jvm没有足够的空间给这个单个的partition可能会引发OOM异常。取而代之的是,我们展开这些value,小心的、可能的放弃并丢掉这个partition到磁盘如果合适。如果空间足够就全部缓存到内存中,否则如果使用磁盘就放到磁盘,不然直接就返回value DependencyNarrowDependency:一个子partition依赖于多个父partitionShuffleDependency:shuffle stage的输出依赖,在shuffle中,rdd是短暂的因为我们在executor端不需要它 ExecutorAllocationClient与cluster manager请求或杀掉executor的客户端根据我们的调度需要更新集群,依赖于三个信息1 executor的数量,我们需要的全部的executor数,cluster manager不能杀掉任何运行中的executor来达到这个数量,这是我们想要分配的executor数量2 所有要运行的stage中有本地偏好的task数量,包括运行等待和完成的task3 task到运行host的map ExecutorAllocationManager(EAM)一个代理,根据工作负载动态的分配和移除executorEAM维护一个移动的目标executor数量,定期的同步到cluster manager。target的数量从配置的一个初始值开始,并根据等待和运行task数变化在当前的target数量多于需要控制的当前的负载时,会减少target数量。target总是会一次性减到可以运行所以当前运行和等待task的数量当需要响应积压的等待需要调度的task时,会增加target的数量。如果一个队列在N秒内没有排空,则新的executor被加入。如果这个队列仍然在另外的M秒内存在,则更多的executor会被加入。增加的数量在每轮以上一轮的指数级增加,直到达到上限。上限是基于一个配置的属性和当前运行和等待任务的数量。指数增长有双重理由。1 executor应该在开始缓慢的增加,以防万一额外需要的executor数量很小。否则我们增加了多于我们需要的executor数量则我们需要在后面移除他们。2 executor的数量需要快速增加,以防万一executor的数量最大值非常高,否则在繁重的工作负载下性能提升需要很长时间。executor移除的策略很简单,如果一个executor已经空闲了K秒,意味着它没有被调度用于执行任何task,因而移除它。这里没有重试的逻辑,因为我们假定cluster manager最终会异步的执行所有它收到的请求。相关的spark属性如下 成员变量initializing,是否需要一直等待初始化的executor集合被分配,当这个变量为true的时候,我们不会取消未执行的executor请求。这个在下面两种情况会被设置成false1 一个stage被提交2 一个executor的空闲时间超时用于增加减少executor的调度任务是一个定时任务,每100毫秒执行一次调度方法上,首先基于添加时间和我们当前的需要调整我们请求的executor,然后如果一个已存在的executor已经过期了,则杀掉。 updateAndSyncNumExecutorsTarget:更新target数量并同步结果到cluster manager。检查我们已存在的分配和之前的请求超过我们现在的需要。如果满足,truncate target数量并让cluster manager知道以便于它可以取消不需要的等待的请求。如果不满足,并且添加的时间超时,看看我们是否能请求新的executor,并刷新添加时间。 当一个executor(程它为executor X)因为到达了下限而没有被删除,则它不会再被标记位空闲。当有新的executor加入,我们不再在最低下限,则我们必须再次标记executor X为空闲,以使我们不会忘记它是一个被移除的候选。当scheduler的队列是空的时候,就会将addtime设为未设置所有cache的block会被报告给driver,但不包括广播的block当executor执行任务了(busy),就会清除它的idle timeprivate val stageIdToExecutorPlacementHints = new mutable.HashMap[Int, (Int, Map[String, Int])]stageid到tuple的map,tuple是节点和将会在这个节点上运行的task的数量taskstart和blockmanageradded这些事件是在不同的线程执行的,因而顺序不一定,taskstart事件中将对应的executor置为busytaskend,如果executor不再运行任何调度的任务,则标记为idle如果task失败,则会将scheduler置为积压任务的状态,将这个task从这个stage对应的task列表中移除

资源下载

更多资源
Mario

Mario

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

Spring

Spring

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

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部分的功能。

用户登录
用户注册