首页 文章 精选 留言 我的

精选列表

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

Java使用位域进行多标记(状态)管理

Android中位域的应用 在Android中,我们会经常用到或者看到以下这样的代码 : public class ExampleUnitTest { @Test public void gravityTest(LayoutParams params) { // 视图在layout中右下角显示 params.gravity = Gravity.RIGHT | Gravity.BOTTOM; } @Test public void intentFlagTest(Intent intent) { // 清空任务栈中所有旧的activity intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 如果activity已存在于栈中,清空该activity之上的所有任务 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); } @Test public void windowMangerFlags(WindowManager.LayoutParams params) { // 不拦截视图以外的事件,在锁屏中显示 params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; } } 通过一个 int字段,来添加多个 标志或者状态. 一个int字段,能够管理多个标记(状态)值. 如此神奇的操作怎样实现的呢? 答案就是通过位运算来实现. 位操作基础 java中提供的基础位运算符有 与(&),或(|),非(~),异或(^),左移<<,右移(>>)和无符号右移(>>>). 除了位非(~)是一元操作符外,其它的都是二元操作符。 下面只介绍本文中,使用到的位操作 按位与 A & B : A和B对应的二进制数位都为1时,结果才为1,其他情况为0. A = 001101 // 13 B = 100101 // 37 A & B = 000101 // 5 按位或 A | B : A和B对应的二进制数位都为0时,结果才为0,其他情况为1. A = 001101 // 13 B = 100101 // 37 A | B = 101101 // 45 按位非 ~A : 将a的二进制表示每一位进行取反操作,0变1,1变0. 相当于相反数 - 1 A = 001101 // 13 ~A = 11111111111111111111111111110010 // int32位,补码表示,第一位为符号位 // 根据上诉补码转原码为 // 10000000000000000000000000001110 // -14 左移操作 A << B:将A的二进制表示的每一位向左移B位,左边超出的位截掉,右边不足的位补0。 在取值范围内,移动一位相当于乘2. A = 001101 // 13 A << 1 = 011010 // 26 原理与实践 通常情况下,如果多个状态或者标记相互之间有关联, 如布局方向,上下左右,左上,居中 ... 等.我们可能会为每一个标记设置一个变量. boolean left = false; boolean right = false; ... void setLeft(boolean b); void setRight(boolean b); ... 这种情况下, 有4个标记相互关联,并且能产生新的标记,那么我们就需要设置4个标记变量,然后只能通过一系列的set方法来转换状态.如 v.setLeft(true); v.setRight(true); 这样就会使得,各个状态不易维护和判断,状态越多,情况越复杂,代码会显得冗长难以维护. 像这种,独立状态(标记)之间相互组合可以产生新的状态(标记),且每个独立状态(标记)只有true或者false值的,我们可以使用位域的概念来管理这些状态. 它的核心思想就是将, int 数值看做是 二进制数位表示.如果有四个状态就可以像这样 0000,用四位二进制表示,每一个二进制位都可以表示一种状态. 然后通过 位运算,来提取或添加标记位.四位对应的组合状态有16个. 而我们,只需要通过一个int变量就能够管理这些状态. 当参与的状态(标记)越多时,如果使用单独的标记变量,就需要生成越多的变量,而用位域,这种独立状态为不管有多少个,都可以用一个变量表示.int类型最多存放32个独立状态 下面我们来看具体实现.(简单的模仿Gravity类的一部分功能) public class Gravity { // 二进制表示 0001 public static final int LEFT = 1; // 二进制表示 0010 public static final int RIGHT = LEFT << 1; // 二进制表示 0100 public static final int TOP = LEFT << 2; // 二进制表示 1000 public static final int BOTTOM = LEFT << 3; // 水平居中, 二进制表示 0011 public static final int HORIZONTAL_CENTER = LEFT | RIGHT; // 垂直居中, 二进制表示 1100 public static final int VERTICAL_CENTER = TOP | BOTTOM; // 居中, 二进制表示 1111 public static final int CENTER = HORIZONTAL_CENTER | VERTICAL_CENTER; // 默认左上角, 二进制表示 0101 public static final int DEFAULT = LEFT | TOP; // 存放标志位 private int mFlags = DEFAULT; // 设置标记位,会清除原来的标记 public void setFlags(int flags) { mFlags = flags; } // 添加标记位,在原来的基础上添加 public void addFlags(int flags) { mFlags |= flags; } // 清除指定的标记 public void clearFlags(int flags) { mFlags &= ~flags; } // 清除所有标记,设为默认 public void clears() { mFlags = DEFAULT; } // 判断是否存在指定的标记 public boolean hasFlags(int flags) { return (mFlags & flags) == flags; } // 判断是否 只有指定的标记 public boolean onlyFlags(int flags) { return mFlags == flags; } public void apply() { String des = "左上角"; if (hasFlags(CENTER)) { des = "整体居中"; } else if (hasFlags(HORIZONTAL_CENTER)) { if (hasFlags(BOTTOM)) des = "水平居中,竖直向下"; else des = "水平居中,竖直向下"; } else if (hasFlags(VERTICAL_CENTER)) { if (hasFlags(RIGHT)) des = "竖直居中,水平向右"; else des = "竖直居中,水平向左"; } else if (hasFlags(LEFT | BOTTOM)) { des = "左下角"; } else if (hasFlags(RIGHT | TOP)) { des = "右上角"; } else if (hasFlags(RIGHT | BOTTOM)) { des = "右下角"; } System.out.println("你选择的布局是 : " + des); } } 具体的调用实现 : public class Main { public static void main(String[] args) { Gravity gravity = new Gravity(); // 设置为 右下角 gravity.setFlags(Gravity.BOTTOM | Gravity.RIGHT); gravity.apply(); // 添加 left后,变为 水平居中,竖直向下 gravity.addFlags(Gravity.LEFT); gravity.apply(); // 判断是否 水平居中, 返回为 true gravity.hasFlags(Gravity.HORIZONTAL_CENTER); // 添加top后,变为 整体居中了 gravity.addFlags(Gravity.TOP); gravity.apply(); // 删掉 bottom和left 之后,变为右上角了 gravity.clearFlags(Gravity.BOTTOM | Gravity.LEFT); gravity.apply(); } } // 结果 你选择的布局是 : 右下角 你选择的布局是 : 水平居中,竖直向下 你选择的布局是 : 整体居中 你选择的布局是 : 右上角

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

centos6 多段Ip添加shell脚本

#!/bin/bash export device=`ifconfig|grep eth0|head -n 1|awk '{print ($1)}'` export ipcfg_pre="/etc/sysconfig/network-scripts/ifcfg-eth1-range" awktmp=`mktemp` msg=`mktemp` ip_txt=`mktemp` ifcfgs="$(find ${ipcfg_pre%/*} -name ${ipcfg_pre##*/}*)" if test ! -z "$ifcfgs";then echo "发现如下已有配置文件是否删除(yes/no)?" echo "$ifcfgs" select var in "yes" "no" do if test "$var" = "yes";then rm -f $ifcfgs break; else break; fi done fi #脚本保存进 临时文件 不再使用a.awk文件。 cat >$awktmp <<EOF #!/usr/bin/awk -f BEGIN{ ipcfg_pre="${ipcfg_pre}" #你需要修改 ipcfg_pre 为自己的路径前缀 device=ENVIRON["device"] clone_num=1; numofpc[24]=253 numofpc[24]=125 numofpc[26]=61 numofpc[27]=29 numofpc[28]=13 numofpc[29]=5 } function ip_str(iplist){ return sprintf("%s.%s.%s.%s",ip_list[1],ip_list[2],ip_list[3],ip_list[4]); } function gen_mask(num,mask_bin, _ARGVEND_,sum,bits){ #把掩码由数字转换成数组 _i=1; mask_bin[1]=0; for (;_i*8 <=num && _i<=4;_i++){ mask_bin[_i]=255; } bits=num-(_i-1)*8; sum=0; for(;bits>0;bits--){ sum=sum+2^(8-bits); } mask_bin[_i]=sum; _i++; for(;_i<=4;_i++){ mask_bin[_i]=0; } } { ipfile=sprintf("%s%s",ipcfg_pre,NR); split(\$0,ip,"/"); ip_mask=ip[2]; split(ip[1],ip_list,"."); #ip_list 列表保存了 ip 的四个 字节值 ip_start=ip_list[4]+2; ip_end=ip_start+numofpc[ip_mask]-1; printf("DEVICE=%s\n",device)>ipfile printf("BOOTPROTO=static\n")>>ipfile printf("CLONENUM_START=%d\n",clone_num)>>ipfile ip_list[4]=ip_start; printf("IPADDR_START=%s\n",ip_str(ip_list))>>ipfile ip_list[4]=ip_end; printf("IPADDR_END=%s\n",ip_str(ip_list))>>ipfile clone_num+=numofpc[ip_mask]; printf("ONBOOT=yes\n")>>ipfile gen_mask(ip_mask,ip_list) netmask=ip_str(ip_list) printf("NETMASK=%s\n",netmask)>>ipfile } EOF chmod a+x $awktmp msg=`mktemp` cat >$msg <<EOF 请输入IP地址和掩码每行一行(不可出现空白行) 如: 45.34.89.40/29 23.91.3.0/28 23.91.8.32/28 23.91.18.160/28 23.91.28.128/28 EOF vi +":!cat $msg" $ip_txt #service network restart test -e $ip_txt && awk -f $awktmp $ip_txt service network restart rm -f $awktmp $msg $ip_txt rm -f ipcfg.sh ===================================================== 此脚本只适用于 45.34.89.40/29 23.91.3.0/28 23.91.8.32/28 23.91.18.160/28 23.91.28.128/28 这种格式IP段添加,请注意脚本网卡名称和机器网卡名称是否一致 使用方法,命名为ipcfg.sh 1. 会提示IP文件是否已经存在,让选择是否删除。我们只用于第一次添加。尽量不要去补充添加。 2. 按回车键,然后按 i 进入编辑模式,输入IP段。iP段一个一行,不要有空格。 保存。

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

利用 Android Studio 和 Gradle 打包多版本APK

在项目开发过程中,经常会有需要打包不同版本的 APK 的需求。 比如 debug版,release版,dev版等等。 有时候不同的版本中使用到的不同的服务端api域名也不相同。 比如 debug_api.com,release_api.com,dev_api.com等等。 不同的版本对应了不同的 api 域名,还可能对应不同的 icon 等。 如果每次都在打包前修改我们都手动来修改,这样实在是不够方便。 但如果我们使用了 Android Studio 和 Gradle,这个麻烦就可以轻松省去。 具体方式如下: 在 Android Studio 中打开 build.gradle(Module中)的 android 节点下添加如下代码 buildTypes { //这里的名字自定义,不要求大小写 release{ // 这里是在 applicationId 中添加了一个后缀。所以『.』要加上 applicationIdSuffix ".release" // 这里的作用是选择是否混淆代码 minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } dev{ applicationIdSuffix ".dev" minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // 这里是为了不同过的版本设置一些特殊的参数,并不直接和 buildType 关联。 //例如:使用 buildType 中的 dev 版本,也可以使用 flavors_release 里面设置的自定义参数。这需要自己按照需求制定。 productFlavors{ //自定义名字不过不能和上面buildType中相同,不然Gradle编译会不通过。在这里使用了『flavors_』前缀以便区分。 flavors_release{ // manifestPlaceholders中写到的『str』,『package_name』不支持用大写,否则Gradle编译会不通过。 // 这里所设置的变量可以直接使用在『AndroidManifest.xml』中,使用方式为:${package_name} // android:label="${package_name}" manifestPlaceholders = [str:"releaseStr",package_name:"com.sunhz.mvptest.release"] // 这里的参数是为了在 java 代码中使用,具体的使用方式为:context.getResources().getString(R.string.strKey); resValue("string" , "strKey","releaseStrValue") } flavors_dev{ manifestPlaceholders = [str:"devStr",package_name:"com.sunhz.mvptest.dev"] resValue("string" , "strKey","devStrValue") } } 上面设置完成后,我们要在哪里使用它? 使用方式如下: 在 Android Studio 的工具栏中,找到『Build』项,找到『Generate Signed APK…』。 选择 Module -> 创建 APK key,或者输入 APK key密码 -> 关键来了!如下图。 在『BuildType』处,选择我们在 build.gradle 中设置的两个 BuildType,分别是releas,dev,debug。其中『debug』为 Android Studio 自带的。 在『Flavors』处,选择我们在 build.gradle 中设置的两个Flavors,以方便直接使用定义在 build.gradle 中自定义的参数。 所以! 上面我有提到说,buildType 和 Flavors 并没有直接的联系。 他们可以根据用户需求互相配合使用。如上图,BuildType 选择了 release,但 Flavors 选择的却是 flavors_dev。 到此基本的使用就全部说完了。 这里有一个问题,打出来的不同版本的包,全部都能够在同一部手机上安装,且能够将两个包全都发布到 Google 的市场上去这是为什么呢? 这里就要提到在 BuildType 中我们所设置的『applicationIdSuffix』属性了,按照这个属性的字面翻译为:『applicationId 的后缀』,那这里又来了一个问题,『applicationId』是什么? 其实这个『applicationId』属性,实际上在项目创建完成后就存在于 build.gradle 中。在 android 节点下的 defaultConfig 节点中。而且默认的 applicationId 和 AndroidManifest.xml 中的 package 属性相同。 如下图: 我们能够看到,这两个属性的默认值是相同的。 applicationId 和 packageName 它们是什么关系? 默认创建项目后,两者相同。如果需要根据不同的需求构建不同版本的APK,这时我们通过设置『applicationIdSuffix』可以做到。 这里有一个值得注意的现象。 举个例子,我们在打包时使用了 dev 类型,将打包出来的 APK 软件安装到手机中。 使用如下代码,获取我们手机上所有程序的packageName。 PackageManager packageManager = mContext.getPackageManager(); List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS); List<String> packageNameList = new ArrayList<String>(); for (PackageInfo packageInfo : packageInfoList) { packageNameList.add(packageInfo.packageName); } 我们打印出来的包名信息中,会出现 com.spencer_dev.test.dev 。并没有出现 com.spencer_dev.test 。 但是! 如果通过反编译工具,将 APK 包进行反编译直接查看源代码,在 java 代码所在的 src 目录中的包名,还和我们设置的一样,为 com.spencer_dev.test 。可 AndroidManifest.xml 中的 package 和 BuildConfig 类中的 APPLICATION_ID 已经变成了 com.spencer_dev.test.dev 。 applicationId 和 packageName 它们各自代表什么? 按照上面的结果来说, package 代表了 java 代码中的包名。 applicationId 代表了应用中的唯一标识。和应用签名一起用来区别和其他应用不同。我想这也就是为什么 Google 市场能够允许相同应用不同 applicationId 的原因。 长按下方二维码就可以识别关注 本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/1737795,如需转载请自行联系原作者

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

Android SDK和N多Android开发资源

文章目录[点击展开](?)[+] 开发资源 本文收集整理Android开发需要的Android SDK、工具、Android开发教程、Android设计规范,免费的设计素材等。 欢迎大家推荐自己在Android开发过程中用的好用的工具、学习开发教程、用到设计素材, Android SDK在线更新镜像服务器 腾讯Bugly 镜像 腾讯Bugly 镜像:android-mirror.bugly.qq.com端口:8080 速度绝对的给力,公司宽带是广东电信,几乎达到满速。 大连东软镜像 大连东软信息学院镜像服务器地址:mirrors.neusoft.edu.cn端口:80 家里用的铁通光纤,使用腾讯的镜像速度时好时坏,但这个镜像倒是速度给力。 配置方法 项目地址 github:https://github.com/inferjay/AndroidDevTools 官网:http://www.androiddevtools.cn/ 其它:http://tools.android-studio.org/index.php 如果要下载Android Developer Tools(Eclipse开发Android应用),可以选择ADT Bundle,它包含了Eclipse、ADT插件和SDK Tools,是已经集成好的IDE,只需安装好Jdk即可开始开发,推荐初学者下载ADT Bundle,不用再折腾开发环境。 本文转自赵青青博客园博客,原文链接:http://www.cnblogs.com/zhaoqingqing/p/5431255.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

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

用户登录
用户注册