日期: 2021 年 4 月 15 日

iOS--项目目录组织及生成脚本

在iOS应用开发,Xcode项目目录是随意组织的,这样一来,就会导致不同的人就会有不同的组织方式。从这一点来看,Xcode的项目组织形式上个人觉得就没有Android开发(无论是eclipse还是as)项目组织形式好了。

这段时间为了规范自己的编码目录组织形式,参考网上的资料,结合自己的习惯,定下了以下的一个iOS项目目录组织结构。这个结构并不完美,有好的想法和好的思路会继续更新,逐渐完善整个结构。

资源下载:iOS项目框架脚本

一、目录结构
.
| _ Expand (扩展内容)
| _ _ Category (自定义Category)
| _ _ Macros (宏定义)
| _ _ _ _ JHMacros.h (项目宏定义)
| _ _ _ _ JHMacros.h (全局默认宏定义)
| _ _ _ _ JHThirdMacros.h (项目第三方宏定义)
| _ _ Tool (工具类)
| _ Main (主逻辑及界面View)
| _ _ Module1 (模块1)
| _ _ _ _ Controller (控制器)
| _ _ _ _ Model (数据模型)
| _ _ _ _ Other (其他文件)
| _ _ _ _ Protocal (协议)
| _ _ _ _ Service (服务逻辑)
| _ _ _ _ View (自定义View视图)
| _ _ _ _ _ _ Cell (Cell视图)
| _ _ _ _ _ _ SubView (子视图)
| _ _ Module2 (模块2)
| _ _ _ _ Controller
| _ _ _ _ Model
| _ _ _ _ Other
| _ _ _ _ Protocal
| _ _ _ _ Service
| _ _ _ _ View
| _ _ _ _ _ _ Cell
| _ _ _ _ _ _ SubView
| _ _ Public (公共内容)
| _ _ _ _ Controller
| _ _ _ _ Model
| _ _ _ _ Other
| _ _ _ _ Protocal
| _ _ _ _ Service
| _ _ _ _ View
| _ _ _ _ _ _ Cell
| _ _ _ _ _ _ SubView
| _ Resource (资源)
| _ _ Font (字体资源)
| _ _ Image (图片资源)
| _ _ _ _ Module1.xcassets (模块1图片资源)
| _ _ _ _ Module2.xcassets (模块2图片资源)
| _ _ _ _ Public.xcassets (公共资源)
| _ _ Plist (Plist文件)
| _ SDKFile (第三方SDK)
| _ Vendor (开源项目代码)

二、生成脚本说明
本生成脚本共包含2个文件,一个是项目信息配置文件,一个是脚本程序。

1. 项目信息配置文件(JHFrameworkInitialization.plist)
项目信息配置文件为一个plist文件,包含两个key:projectName和Modules,分别指定项目的项目名称及项目的模块数组。项目名称*好是首字母大写并符合驼峰命名法原则,Modules是一个数组,若项目不能明显区分模块,则不需填写。 该文件需和脚本程序文件在同一目录,否则会出现找不到配置文件的错误。

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>ProjectName</key>
<string>OMGProject</string>
<key>Modules</key>
<array>
<string>Module1</string>
<string>Module2</string>
</array>
</dict>
</plist>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2. 脚本程序(JHFrameworkInitialization.sh)
其实这个脚本程序是很好理解的,只要有上述的项目目录组织结构,接着就基本使用mkdir命令来生成对应的文件即可。生成完成后需手动把整个结构文件夹添加

#!/bin/sh

echo “”
echo “————————————-”
echo “- 初始化JH iOS框架 -”
echo “————————————-”

echo “”
echo “将在以下目录新建:”
echo $PWD
echo “”

# 通过Plist文件获取当前配置数据
infoPlistFilePath=”JHFrameworkInitialization.plist”
if [[ -f infoPlistFilePath ]]; then
echo “找不到项目信息配置文件(JHFrameworkInitialization.plist)”
return
fi
projectName=$(/usr/libexec/PlistBuddy -c “print ProjectName” ${infoPlistFilePath})
modules=$(/usr/libexec/PlistBuddy -c “print Modules” ${infoPlistFilePath})

# 判断是否存在JH iOS框架文件
JHPath=”JHFramework”
if [ -a “$JHPath” ]; then
rm -rf $JHPath
fi
mkdir $JHPath

# 创建Main文件夹
echo “1.创建Main文件夹…”
mkdir $JHPath”/Main”
mkdir $JHPath”/Main/Public”
mkdir $JHPath”/Main/Public/Controller”
mkdir $JHPath”/Main/Public/View”
mkdir $JHPath”/Main/Public/View/Cell”
mkdir $JHPath”/Main/Public/View/SubView”
mkdir $JHPath”/Main/Public/Model”
mkdir $JHPath”/Main/Public/Other”
mkdir $JHPath”/Main/Public/Protocal”
mkdir $JHPath”/Main/Public/Service”
# mkdir $JHPath”/Main/Preview”
# mkdir $JHPath”/Main/Base”
echo ” Main文件夹创建成功!”

# 创建Expand文件夹
echo “2.创建Expand文件夹…”
mkdir $JHPath”/Expand”
mkdir $JHPath”/Expand/Category”
mkdir $JHPath”/Expand/Macros”
mkdir $JHPath”/Expand/Tool”
echo ” Expand文件夹创建成功!”

# 创建Resource文件夹
echo “3.创建Resource文件夹…”
mkdir $JHPath”/Resource”
mkdir $JHPath”/Resource/Font”
mkdir $JHPath”/Resource/Image”
mkdir $JHPath”/Resource/Image/Public.xcassets”
# mkdir $JHPath”/Resource/Global”
mkdir $JHPath”/Resource/Plist”
echo ” Resource文件夹创建成功!”

# 创建SDKFile文件夹
echo “4.创建SDKFile文件夹…”
mkdir $JHPath”/SDKFile”
echo ” SDKFile文件夹创建成功!”

# 创建模块文件夹
echo “5.创建Vendor文件夹…”
mkdir $JHPath”/Vendor”
echo ” Vendor文件夹创建成功!”

# 初始化JHMacros.h
echo “6.创建JHMacros.h文件…”
macrosPath=$JHPath”/Expand/Macros/JHMacros.h” # JHMacros.h位置
echo “//” >>$macrosPath
echo “// JH常用宏定义(尽量不要在这里增加项目的宏定义)” >>$macrosPath
echo “// JHMacros.h” >>$macrosPath
echo “// “$projectName >>$macrosPath
echo “//” >>$macrosPath
echo “// Created by JH on $(date +%m/%d/%y).” >>$macrosPath
echo “// Copyright © 2016 JH. All rights reserved.” >>$macrosPath
echo “//” >>$macrosPath
echo “” >>$macrosPath
echo “#ifndef JHMacros_h” >>$macrosPath
echo “#define JHMacros_h” >>$macrosPath
echo “” >>$macrosPath
echo “// 导入必要的头文件” >>$macrosPath
echo “#import \”JHThridMacros.h\”” >>$macrosPath
echo “#import \”JH”$projectName”Macros.h\”” >>$macrosPath
echo “” >>$macrosPath
echo “// 设备Size常量” >>$macrosPath
echo “#define JH_SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width // 屏幕宽度” >>$macrosPath
echo “#define JH_SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height // 屏幕高度” >>$macrosPath
echo “#define JH_TABBAR_HEIGHT 49.0 // TabBar高度” >>$macrosPath
echo “#define JH_STATUSBAR_HEIGHT 20.0 // 状态栏高度([[UIApplication sharedApplication] statusBarFrame].size.height)” >>$macrosPath
echo “#define JH_NAVIGATIONBAR_HEIGHT 44.0 // NavigationBar高度” >>$macrosPath
echo “” >>$macrosPath
echo “// 设备信息常量” >>$macrosPath
echo “#define JH_SYSTEM_NAME [UIDevice currentDevice].systemName // 设备系统名称” >>$macrosPath
echo “#define JH_SYSTEM_VERSION [UIDevice currentDevice].systemVersion // 设备系统版本” >>$macrosPath
echo “#define JH_UUID [[UIDevice currentDevice].identifierForVendor UUIDString] // UUID,每次安装app都会不一样” >>$macrosPath
echo “” >>$macrosPath
echo “// NSUserDefaults” >>$macrosPath
echo “#define JH_USERDEFAULTS [NSUserDefaults standardUserDefaults]” >>$macrosPath
echo “” >>$macrosPath
echo “// 关于文件管理的常量” >>$macrosPath
echo “#define JH_FILE_MANAGER [NSFileManager defaultManager] // 文件管理者” >>$macrosPath
echo “#define JH_SANDBOX_DOCUMENTS_PATH [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] // sandbox中documents文件夹路径” >>$macrosPath
echo “#define JH_SANDBOX_LOG_DERECTORY [JH_SANDBOX_DOCUMENTS_PATH stringByAppendingPathComponent:@”JHLog”] // 日志缓存路径” >>$macrosPath
echo “” >>$macrosPath
echo “#endif /* JHMacros_h */” >>$macrosPath
echo ” JHMacros.h文件创建成功”

# 初始化JHThirdMacros.h
echo “7.创建JHThirdMacros.h文件…”
macrosPath=$JHPath”/Expand/Macros/JHThirdMacros.h” # JHThirdMacros.h位置
echo “//” >>$macrosPath
echo “// JH第三方SDK宏定义” >>$macrosPath
echo “// JHThridMacros.h” >>$macrosPath
echo “// “$projectName >>$macrosPath
echo “//” >>$macrosPath
echo “// Created by JH on $(date +%m/%d/%y).” >>$macrosPath
echo “// Copyright © 2016 JH. All rights reserved.” >>$macrosPath
echo “//” >>$macrosPath
echo “” >>$macrosPath
echo “#ifndef JHThridMacros_h” >>$macrosPath
echo “#define JHThridMacros_h” >>$macrosPath
echo “” >>$macrosPath
echo “” >>$macrosPath
echo “#endif /* JHThridMacros_h */” >>$macrosPath
echo ” JHThirdMacros.h文件创建成功”

# 初始化应用<ProjectName>Macros.h
if [[ $projectName != “” ]]; then
echo “8.创建JH”$projectName”Macros.h文件…”
macrosPath=$JHPath”/Expand/Macros/JH”$projectName”Macros.h” # JH<ProjectName>Macros.h位置
echo “//” >>$macrosPath
echo “// 本应用(”$projectName”)宏定义” >>$macrosPath
echo “// JH”$projectName”Macros.h” >>$macrosPath
echo “// “$projectName >>$macrosPath
echo “//” >>$macrosPath
echo “// Created by JH on $(date +%m/%d/%y).” >>$macrosPath
echo “// Copyright © 2016 JH. All rights reserved.” >>$macrosPath
echo “//” >>$macrosPath
echo “” >>$macrosPath
echo “#ifndef JH”$projectName”Macros_h” >>$macrosPath
echo “#define JH”$projectName”Macros_h” >>$macrosPath
echo “” >>$macrosPath
echo “” >>$macrosPath
echo “#endif /* JH”$projectName”Macros_h */” >>$macrosPath
echo ” JH”$projectName”Macros.h文件创建成功”
fi

# 创建模块文件夹
echo “9.创建模块文件夹…”
for module in $modules
do
if [[ ${module} != “Array” && ${module} != “{” && ${module} != “}” ]]; then
mkdir $JHPath”/Main/”$module
mkdir $JHPath”/Main/”$module”/Controller”
mkdir $JHPath”/Main/”$module”/View”
mkdir $JHPath”/Main/”$module”/View/Cell”
mkdir $JHPath”/Main/”$module”/View/SubView”
mkdir $JHPath”/Main/”$module”/Model”
mkdir $JHPath”/Main/”$module”/Other”
mkdir $JHPath”/Main/”$module”/Protocal”
mkdir $JHPath”/Main/”$module”/Service”
mkdir $JHPath”/Resource/Image/”$module.xcassets
fi
done
echo ” 模块文件夹创建成功!”

echo “”
echo “————————————-”
echo “- 初始化JH iOS框架完成 -”
echo “————————————-”
echo “”

iOS--中文排序、全拼音排序

在做项目的时候,总遇到排序问题,英文排序是很简单的,直接使用compare方法就可以实现了,但是一旦遇到中文,就显得麻烦了。

iOS和java不同,java能进行中文字符串的比较,而iOS却没有这个功能。于是乎,iOS中的中文排序就要自己想办法了。相信很多人想到的方法就是获得中文字符串的拼音,再进行排序了。

之前也找过中文排序的相关文章,想必*出名的就是ChineseString.h和pinyin.c文件(或者其变体)了,对于这个pinyin.c文件里密密麻麻的我表示我没认真看懂~~,自己想着就是中文拼音的对应表之类的。但是我使用这两个文件会出现问题的,排序是有进行排序了,但是并不是按照严格的全拼音排序,它只是对中文字符串首字母进行了排序,之后的就没有排了。

在某些场景中,这的确就是足够了,但是现在我需要的是全拼音排序,就是要对中文字符串整个拼音排序。在对着pinyin.c一大串没看懂的代码面前,想着还是自己想办法弄一个吧。在这个过程中,获得拼音是*个难关,之后的通过拼音进行排序说到底就是进行英文字符串的比较。幸好,*终还是在网上找到获得中文字符串拼音的方法。

首先总体思路是这样的:

1. 获得拼音进行比较排序是必须的了,排序就意味着存在数组,但是原本的中文字符串该是如何存储的呢,应该怎样存在数组中呢。我自个儿想了三种方式,一是简单直接的中文字符串数组。接着想着有时候需要排序的中文字符串可能还附加其他的属性,于是有了第二中方式,就是使用字典(NSDictionary)存储需要排序的中文字符串以及其他属性。一个例子就是现在需要对通讯录的人名排序,而通讯录每个人除了人名,至少还包含电话号码,那么就要确保按照人名排序完成后,电话号码也相应的进行了排序了,那么在这个例子中使用第二种方式就是通讯录就是一个数组,而数组的元素就是字典,字典包含了两个属性,一个是人名,另一个是电话号码。而第三种方式是从第二种方式延伸出来的,还是以通讯录排序为例子,我可以把通讯录中每个人都看成一个类的实例(对象),这样人名和电话号码就是类中的属性,这样的话,通讯录是一个数组,而数组的元素不再是字典,而是一个个类的实例了。

*种方式数组初始化Demo:

NSArray *a1 = @[@”张三”, @”李三”, @”li三”, @”qeri三”, @”rei三”, @”lbcx三”, @”kjh三”, @”照三”, @”于三”, @”破三”, @”梁三”];
第二种方式数组初始化Demo:

NSArray *a2 = @[
@{@”name”:@”张三”, @”num”:@”1″},
@{@”name”:@”李三”, @”num”:@”2″},
@{@”name”:@”li三”, @”num”:@”3″},
@{@”name”:@”qeri三”, @”num”:@”4″},
@{@”name”:@”rei三”, @”num”:@”5″},
@{@”name”:@”lbcx三”, @”num”:@”6″},
@{@”name”:@”kjh三”, @”num”:@”7″},
@{@”name”:@”照三”, @”num”:@”8″},
@{@”name”:@”于三”, @”num”:@”9″},
@{@”name”:@”破三”, @”num”:@”10″},
@{@”name”:@”梁三”, @”num”:@”11″}];

第三种方式数组初始化Demo:(这里说明一下,JHChineseInfo是只有一个属性(JHChineseString)的类,如果要使用这种方式进行排序,自定义的类必须继承JHChineseInfo,就如下面的SubChineseInfo,这是这种方式的一点限制,如有大神路过,请给点改进的意见,谢谢~)

JHChineseInfo *ci1 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci2 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci3 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci4 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci5 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci6 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci7 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci8 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci9 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci10 = [[JHChineseInfo alloc] init];
JHChineseInfo *ci11 = [[JHChineseInfo alloc] init];
ci1.JHChineseString = @”张三”;
ci2.JHChineseString = @”李三”;
ci3.JHChineseString = @”li三”;
ci4.JHChineseString = @”qeri三”;
ci5.JHChineseString = @”rei三”;
ci6.JHChineseString = @”lbcx三”;
ci7.JHChineseString = @”kjh三”;
ci8.JHChineseString = @”照三”;
ci9.JHChineseString = @”于三”;
ci10.JHChineseString = @”破三”;
ci11.JHChineseString = @”梁三”;
NSArray *a3 = @[ci1, ci2, ci3, ci4, ci5, ci6, ci7, ci8, ci9, ci10, ci11];
或者:
SubChineseInfo *sci1 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci2 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci3 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci4 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci5 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci6 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci7 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci8 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci9 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci10 = [[SubChineseInfo alloc] init];
SubChineseInfo *sci11 = [[SubChineseInfo alloc] init];
sci1.JHChineseString = @”张三”;
sci1.num = @”1″;
sci2.JHChineseString = @”李三”;
sci2.num = @”2″;
sci3.JHChineseString = @”li三”;
sci3.num = @”3″;
sci4.JHChineseString = @”qeri三”;
sci4.num = @”4″;
sci5.JHChineseString = @”rei三”;
sci5.num = @”5″;
sci6.JHChineseString = @”lbcx三”;
sci6.num = @”6″;
sci7.JHChineseString = @”kjh三”;
sci7.num = @”7″;
sci8.JHChineseString = @”照三”;
sci8.num = @”8″;
sci9.JHChineseString = @”于三”;
sci9.num = @”9″;
sci10.JHChineseString = @”破三”;
sci10.num = @”10″;
sci11.JHChineseString = @”梁三”;
sci11.num = @”11″;
NSArray *a4 = @[sci1, sci2, sci3, sci4, sci5, sci6, sci7, sci8, sci9, sci10, sci11];

2. 获得中文字符串的拼音
函数- (NSString*) chineseStringTransformPinyin: (NSString*)chineseString

// 拼音字段
NSMutableString *tempNamePinyin = [chineseString mutableCopy];
CFStringTransform((__bridge CFMutableStringRef)tempNamePinyin, NULL, kCFStringTransformMandarinLatin, NO);
CFStringTransform((__bridge CFMutableStringRef)tempNamePinyin, NULL, kCFStringTransformStripDiacritics, NO);
这个方法就是从万能的网上寻找回来的,具体说明的话当时看看了,没记录网址就忘了。现在自己产生了一个问题,不知这个方法在效率上是否*优,还有没有更好的方法。在此再请路过的大神知道的指点一下~~

3. 这一步就开始进行中文排序了,上述的三种方式分别对应了三个方法:

1)- (NSArray*) chineseSortWithStringArray: (NSArray*)stringArray;

stringArray必定要是字符串数组,就是数组的元素就是需要排序的中文字符串

2)- (NSArray*) chineseSortWithDictionaryArray: (NSArray*)dictionaryArray andFieldKey: (NSString*)fieldKey

dictionaryArray是字典数组,就是数组的元素是字典,其中key值为fieldKey对应的值就是需要排序的中文字符串

3)- (NSArray*) chineseSortWithObjectArray: (NSArray*)objectArray

objectArray是对象数组,就是数组的元素一定要是JHChineseInfo或者其子类(一般如需自定义就自定义一个子类出来,把需要排序的中文字符串字段赋给JHChineseString属性即可)

排序关键代码(其实就是通过pinyin字段进行英文字符串比较获得排序结果):

[tempArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 objectForKey:@”pinyin”] compare:[obj2 objectForKey:@”pinyin”]];
}];
*终返回结果。

我把获得拼音以及三种方式的函数独立出来了,在使用的时候只需要导入JHChineseSort.h、JHChineseSort.m、JHChineseInfo.h以及JHChineseInfo.m四个文件即可调用。

至此,完结~

如有问题获建议,可一起讨论,共同学习~

Android在程序运行中申请权限

在程序运行过程中申请权限
这里用CALL_PHONE作为实例,参考《*行代码》第二版。
1、首先设置了一个按钮

<Button
android:id=”@+id/make_call”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:text=”Make Call”/>

2、在AndroidManifest.xml文件中声明如下权限:

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.example.runtimepermissiontest”>
//只添加这一行就可以
<uses-permission android:name=”android.permission.CALL_PHONE” />

<application

</application>

</manifest>

如果是Android 6.0之前的版本,现在只需要在按钮中添加打电话逻辑就可以了,但在6.0之后的版本中,CALL_PHONE被列为了危险权限。所以需要申明权限。

3、编写按钮的代码

@Override
public void onClick(View v) {
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
}else{
call();
}
}

call()方法如下:

private void call(){
try{
//Intent.ACTION_CALL可以直接拨打电话
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(“tel:10086″));
startActivity(intent);
}catch(SecurityException e){
e.printStackTrace();
}
}

onRequestPermissionsResult方法:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch(requestCode){
case 1:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
call();
}else{
Toast.makeText(this,”You denied the permission”,Toast.LENGTH_SHORT).show();
}
break;
default:
}
}

1.判断用户是否给我们授权,借助ContextCompat.checkSeifPermission()方法,接受两个参数(*个上下文Context,第二个权限名)

2.把方法的返回值和PackageManager.PERMISSION_GRANTED作比较,相等就说明用户已经授权,不等说明用户没有授权。

3.如果已授权,直接执行拨打电话的逻辑

4.如果没有授权,则需要调用ActivityCompat.requestPermissions()方法来向用户申请授权

5.requestPermissions()方法接受3个参数,*个参数是活动实例,第二个参数是String数组(用来放权限名),第三个参数是请求码,只需要唯一就了

6.然后系统会弹出一个权限申请的对话框,然后用户可以选择同意或者拒*,不管哪种结果都会回调到OnRequestPermissionsResult()方法中,授权结果会封装到grantResults参数中

7.判断一下授权结果,如果同意调用call()方法拨打电话,拒*就放弃操作,弹出失败提示

云计算细分之七大类商业模式

云计算时下可谓风靡一时,正如Gartner咨询公司资深分析师Ben Pring所说:”云计算已经成为大家津津乐道的话题”。但问题是每个人看起来似乎都有自己不同的定义。

“云”是个大家熟悉的名词,但当它与”计算”相结合,它的含义就演变的泛泛而且虚无缥缈。一些分析师和厂商将云计算狭义的定义为效用计算(Utility computing)的升级版本:*基本的就是在网络范围内应用虚拟服务器。其他方面的应用也很广泛。

当我们考虑到IT的实际需求时,云计算的概念也逐渐清晰起来:那就是在不需要增加基础设施投入,新员工培训或者*新软件授权的前提下提升闲置资源性能和能力的一种方法。云计算包含了任何通过网络实时提供订阅型(subscription-based)或者按照使用量付费(pay-per-use)的服务模式,扩展了IT行业现有的能力。

云计算目前还处于萌芽阶段,有大大小小鱼龙混杂的各色厂商在开发不同的云计算服务,从成熟的应用程序到存储服务再到垃圾邮件过滤不一而足。不错,效用模式基础架构供应商是提供多种服务,诸如Salesforce.com这样的SaaS(软件即服务)的供应商亦是如此。如今在很大程度上,IT业界必须个别的去接受云服务,不过云计算的开发商和集成商已经开始初具规模。

根据不同的厂商,分析师和IT用户对云计算的看法,我们将云计算细分如下:

1.软件即服务(SaaS)

这种类型的云计算是采用multitenant架构通过网络浏览器将单个的应用软件推广到数千用户。从用户角度来说,这意味着他们前期无需在服务器或软件许可证授权上进行投资;从供应商角度来看,与常规的软件服务模式相比,维护一个应用软件的成本要相对低廉。迄今为止Salesforce.com是企业应用软件领域中*为知名的供应商,但是软件即服务(SaaS)在人力资源管理软件方面运用比较普遍,还有诸如Workday这样的ERP软件供应商。谁又能预测来自Google和oho Office的软件即服务(SaaS)桌面系统应用软件是否会出现突然的飞跃呢?

2.效用计算(Utility computing)

这种想法本来并无新意,但这种类型的云计算有了Amazon.com, Sun, IBM和其他从事存储服务和IT随需访问的虚拟机厂商的参与就焕发出了新的生命力。早期的企业主要将效用计算作为补充,不会应用在关键性任务需求上。但是时至今日效用计算逐渐在数据中心开始占据一席之地。一些供应商向用户提供解决方案来帮助IT企业从商业服务器开始创建数据中心,诸如3Tera的AppLogic和Cohesive Flexible Technologies的Elastic Server都提供这种随需服务。Liquid Computing公司的LiquidQ也有类似的服务,能帮助企业将内存,I/0,存储和计算容量通过网络集成为一个虚拟的资源池来使用。

3.云计算的网络服务

网络服务与软件即服务(SaaS)是密切相关的,网络服务供应商提供API能帮助开发商通过网络拓展功能性,而不只是提供成熟的应用软件。他们的服务范围从提供分散的商业服务(诸如Strike Iron和Xignite )到涉及到Google Maps, ADP薪资处理流程,美国邮电服务,Bloomberg和常规的信用卡处理服务等的全套API服务。

4.平台即服务(Platform as a service)

平台即服务(Platform as a service)是软件即服务(SaaS)的变种,这种形式的云计算将开发环境作为服务来提供。你可以创建自己的应用软件在供应商的基础架构上运行,然后通过网络从供应商的服务器上传递给用户。比如乐高公司(Legos)就是这么做的。但这些服务会受到厂商设计和容量的限制,因此用户就没有足够的自由。代表公司包括Salesforce.com的Force.com和Coghead。

5.管理服务供应商(MSP)

管理服务是云计算*古老的形式之一,管理服务是面向IT厂商而并非*终用户的一种应用软件,诸如用于电子邮件的病毒扫描服务或者应用软件监控服务。由SecureWorks, IBM和Verizon公司提供的管理安全服务就归为此类,还有目前被Google收购的Postini以云为基础的反垃圾邮件服务。其他的产品还包含桌面系统管理服务,诸如CenterBeam和Everdream提供的产品。

6.服务商业平台

服务商业平台是软件即服务(SaaS)和管理服务供应商(MSP)的混合体,这种云计算服务提供了一种与用户相结合的服务采集器。在贸易领域中应用*为普遍,诸如费用管理系统能允许用户在用户设定的规格范围内从普通平台上订购与所要求的服务和价格相符的旅游产品或者秘书台服务,就好比一个自动化服务局,知名公司包括Rearden Commerce和Ariba。

7.网络集成

云基础服务的集成尚处于初始阶段。软件服务供应商OpSource目前推出了OpSource Services Bus,使用的就是被成为Boomi的云集成技术。软件即服务供应商Workday*近收购了这一领域中的另外一家公司CapeClear,这家ESB(企业服务总线)供应商主要从事B-TO-B商业模式的服务。Grand Central公司也致力于向用户提供集成解决方案,日前被Google所收购。

如今,云计算的运用还不是非常广泛,对于云计算更精确的描述可能是”天空运算”。同时,随着虚拟化和SOA在企业中的逐渐普及,这种想法也开始为大家所认同。可扩展的基础架构应该*终能将每一家企业都*为云的节点。这是个长期可发展的趋势,但是不可否认的是,云计算在很长的时期内还将是业界争论的难点之一。

iOS searchbar拼音和汉字搜索全国城市

*近在做一个地图相关的应用,涉及到全国城市的切换,于是打算把这个记录下来

用到的主要东西有:百度的全国城市列表,txt格式,jasonkit数据解析第三方,tableview,searchabar,汉字转拼音。

%title插图%num%title插图%num

1.首先拿到的是百度的全国城市列表,因为是txt格式的,比较好处理,而且附带经纬度(虽然百度的是火星坐标,但处理起来那是后面的事情,总比没有强),高德的是pdf格式,没有经纬度。这份文件要做些适当的修改不然不能够解析为jason类型。百度的文件做了加密,这里还需要解码~真坑爹,好在不是很复杂,jason在这里只现身一次,得到所需要的字典

%title插图%num%title插图%num

2.汉字转拼音,这个是为了排序和后面的搜索用的,当然,汉字转拼音也是用的代码行,一样很强大,速度也不慢,有一点需要强调的是,转换的时候两个if语句必须都要写上,不然不起作用,这个没细研究。封装好的city对象有名字,拼音,经纬度

%title插图%num%title插图%num

3.排序:因为数组内存放的都是对象,所以需要对对象的某个属性排序才行,这里用的是拼音,方法也很简单%title插图%num%title插图%num

%title插图%num

4.获得所有城市的首字母并将相同首字母的城市封装在同一个城市

列表显示城市列表是按照首字母显示的,所以这个很必要

%title插图%num%title插图%num

*后需要三个数组

A:首字母数组;B:所有城市数组;C:按首字母分类好的所有城市列表

%title插图%num%title插图%num

5.展示所有城市,tableview加载现成的数组,体力活

%title插图%num%title插图%num

6.搜索

搜索的关键是按照拼音和汉字进行搜索的

%title插图%num%title插图%num

拼音搜索的

%title插图%num%title插图%num

demo下载地址http://download.csdn.net/detail/map625/6944965

云计算下的这些细分领域 你都了解吗?

本文写的是云计算下的这些细分领域 你都了解吗?【IT168 评论】云计算的“云”源于绘制互联网的网络图表时的一个习惯——会将其画成一朵云。*受认同的关于云计算含义的解释是,在一个商业供应者的数据中心上通过互联网远程运行工作负载——也就是所谓的“公有云”模式。AWS、Azure、谷歌云等平台都是这一云计算概念的例证。

但是,云计算还有一个更精确的解释:数据中心资源的虚拟化和中心管理。其关键优势是敏捷性:根据工作负载的需求,使用抽象计算、存储和网络等资源,且具备大量的预构建服务。

从客户的角度来看,公有云能够提供一种方式,在不投入新的硬件和软件的情况下,获得新的功能。同时,客户只需按照自己所使用的资源为他们的云供应商支付费用。只要填写web表单,用户就可以设置账户、加速虚拟机或提供新的应用程序。根据客户在运行自己的工作负载时的需求增加更多计算资源,这种特性被称为伸缩性。

云计算下的这些细分领域 你都知道吗?

云计算中可用的服务种类是很多的,不过主要可以分为以下几类:

SaaS(software as a service,软件即服务)

这种类型的公有云在互联网上通过浏览器对应用程序进行交付。*受欢迎的商务级SaaS应用程序有谷歌的G Suite和微软的Office 365;而在企业级应用中,Salesforce独占鳌头。但是几乎所有的企业级应用,包括从Oracle到SAP的ERP套件,都采用SaaS模型。通常,SaaS应用可提供广泛的配置选项以及开发环境,使客户能够自己对代码进行修改和添加。

IaaS(infrastructure as a service,基础设施即服务)

在基础层面上,IaaS公有云供应商提供存储和计算服务。但所有主要公有云供应商提供的服务都是惊人的:高可伸缩数据库、虚拟专用网络、大数据分析、开发工具、机器学习、应用程序监控等等。AWS是*个IaaS供应商,且目前仍是领袖,紧随其后的是微软Azure、谷歌云平台和IBM Cloud。

PaaS(platform as a service,平台即服务)

PaaS所提供的服务和工作流专门针对开发人员,他们可以使用共享工具、流程和API来加速开发、测试和部署应用程序。Saleforce的Salesforce的Heroku和Force.com是非常受欢迎的公共云PaaS产品;Pivotal的Cloud Foundry和红帽的OpenShift可以在本地部署或通过一些主要的公有云来访问。对于企业来说,PaaS可以确保开发人员对已就绪的资源的访问,遵循一定的流程和只使用一个特定的系列服务,运营商则维护底层基础设施。

值得一提的是,专为移动端开发人员使用的各种PaaS一般被称作MBaaS(移动后端即服务),或者只是BaaS(后端即服务)。

云计算下的这些细分领域 你都知道吗?

FaaS(functions as a service,功能即服务)

FaaS,无服务器计算的云实例化,为PaaS增加了另一个抽象层,以便开发人员在堆栈中完全隔*一切优先级低于他们代码的东西。不是去搞虚拟服务器、容器和应用运行时间,而是上传功能代码块,让它们被某个事件触发(例如表单提交或上传文件)。所有主要云都会在IaaS之上提供FaaS:AWS Lambda、Azure Functions、谷歌云Functions以及IBM OpenWhisk。FaaS应用的一个特殊的好处是,在事件发生之前不会使用IaaS资源,可通过降低资源使用率来减少费用。

私有云

私有云可以说是小尺寸的IaaS公有云,使软件可以部署和运行在客户的数据中心。与公有云一样,内部客户可以提供自己的虚拟资源,以构建、测试和运行应用程序,通过计量资源消耗进行收费。对于管理员而言,私有云数据中心*好就是自动化,而*差的情况则是手动配置和管理。VMware的软件定义数据中心栈是*受欢迎的商业私有云软件,虽然OpenStack是开源方面的领袖。

混合云

混合云是私有云与公有云的集成。混合云涉及创建并行环境,是应用程序可以在私有云和公有云之间轻松移动。在其他情况下,数据库可能待在客户数据中心与公有云应用程序集成——在需求高峰期,虚拟化数据中心的工作负载可能会被复制到云。私有云和公有云之间的集成类型差别很大,但他们必须各自互相适应,以成为一个混合云的模式。

云计算下的这些细分领域 你都知道吗?

公有 API(API,应用程序设计接口)

正如SaaS在互联网上为用户交付应用程序,共有API为开发人员提供应用程序功能,可以以编程的方式访问。例如,在构建Web应用时,开发人员经常会利用谷歌地图API提供行车路线;为了集成到社交媒体,开发人员可能会呼吁API通过Twitter或Facebook被保持。Twilio已经建立了一个成功的业务,致力于通过公共API提供电话和消息传递服务。*终,任何企业都可以提供自己的公有API实现客户消费数据和应用程序功能的访问。

iPaaS(integration platform as a service,集成平台即服务)

数据集成是任何具备一定规模的公司的一个关键问题,尤其对于那些大规模采用SaaS的企业而言。iPaaS供应商通常提供预先构建的连接器,为流行的SaaS应用程序和本地企业应用程序之间提供共享数据,尽管供应商可能或多或少地关注B2B电子商务集成、云集成或传SOA风格的集成。

IDaaS(identity as a service,身份即服务)

在私有数据中心和公有云网站上,与云计算相关的*大的安全问题就是管理用户身份及其相关权利和权限。IDaaS供应商保持基于云计算的用户配置文件,验证用户身份,并使访问资源或应用程序基于安全策略、用户组和个人的特权。能够集成各种目录服务(Active directory LDAP,等等),而且这是至关重要的。

协作平台(Collaboration platforms)

协作解决方案如Slack、微软Teams和HipChat已经成为重要的信息沟通平台,是组织内部能够有效地沟通和合作。基本上,这些解决方案是相对简单的SaaS应用程序,支持聊天形式的消息传递以及文件共享和音视频交流。大多数提供API来促进与其他系统的集成,使第三方开发者创建和共享插件,增强功能。

垂直云(Vertical clouds)

在金融、医疗、零售、生命科学和制造行业提供PaaS云使客户建立垂直应用程序,接近行业特定的、API-accessible服务。垂直云可以减少垂直应用程序投放到市场的时间,加速特定领域的B2B集成。大多数垂直云的构建都带着一些培养生态合作伙伴系统的目的。

云计算的吸引力与反对意见

云计算的主要吸引力是减少市场投放时间以及应用程序的动态化的规模扩展。不过,越来越多的开发商正将大量先进的服务引进到云中,并且可以合并到应用程序中,从机器学习到物联网。

虽然有时候企业遗留应用程序会迁移到云来减少数据中心的资源需求,但真正的福利在于利用云服务和“云原生”属性增加新的应用程序。后者包括微服务架构、Linux容器,可增强应用程序的可移植性,容器管理解决方案如Kubernetes基于容器的服务编排。原生云方法和解决方案可以是公有云或私有云的一部分,有助于高效使用Devops风格的工作流。

对公有云的反对意见,一般源于安全问题,虽然主要的公有云供应商已经证明自己的数据中心比一般企业更不容易收到攻击影响。更大的问题是客户与公有云供应商之间安全策略以及身份管理之间的集成。同时,政府的监管可能会禁止客户让敏感数据离开本地。其他一些问题包括服务中断的风险和长期运营成本。

但公有云和私有云都已成为大型应用程序的首选平台,尤其是对于那些需要经常动态地改变规模的客户。更重要的是,现在的公有云供应商在技术开发上一直处在前列。企业选择云之后,会源源不断地被邀请使用一些令人兴奋的新技术。

“云”到底是什么?云计算7种类型细分

云计算时下可谓风靡一时,正如Gartner咨询公司资深分析师Ben Pring所说:”云计算已经成为大家津津乐道的话题”。但问题是每个人看起来似乎都有自己不同的定义。  ”云”是个大家熟悉的名词,但当它与”计算”相结合,它的含义就演变的泛泛而且虚无缥缈。一些分析师和厂商将云计算狭义的定义为效用计算(Utility computing)的升级版本:*基本的就是在网络范围内应用虚拟服务器。其他方面的应用也很广泛。

当我们考虑到IT的实际需求时,云计算的概念也逐渐清晰起来:那就是在不需要增加基础设施投入,新员工培训或者*新软件授权的前提下提升闲置资源性能和能力的一种方法。云计算包含了任何通过网络实时提供订阅型(subscription-based)或者按照使用量付费(pay-per-use)的服务模式,扩展了IT行业现有的能力。

云计算目前还处于萌芽阶段,有大大小小鱼龙混杂的各色厂商在开发不同的云计算服务,从成熟的应用程序到存储服务再到垃圾邮件过滤不一而足。不错,效用模式基础架构供应商是提供多种服务,诸如Salesforce.com这样的SaaS(软件即服务)的供应商亦是如此。如今在很大程度上,IT业界必须个别的去接受云服务,不过云计算的开发商和集成商已经开始初具规模。

根据不同的厂商,分析师和IT用户对云计算的看法,我们将云计算细分如下:

1.软件即服务(SaaS)

这种类型的云计算是采用multitenant架构通过网络浏览器将单个的应用软件推广到数千用户。从用户角度来说,这意味着他们前期无需在服务器或软件许可证授权上进行投资;从供应商角度来看,与常规的软件服务模式相比,维护一个应用软件的成本要相对低廉。迄今为止Salesforce.com是企业应用软件领域中*为知名的供应商,但是软件即服务(SaaS)在人力资源管理软件方面运用比较普遍,还有诸如Workday这样的ERP软件供应商。谁又能预测来自Google和oho Office的软件即服务(SaaS)桌面系统应用软件是否会出现突然的飞跃呢?

2.效用计算(Utility computing)

这种想法本来并无新意,但这种类型的云计算有了Amazon.com, SunIBM和其他从事存储服务和IT随需访问的虚拟机厂商的参与就焕发出了新的生命力。早期的企业主要将效用计算作为补充,不会应用在关键性任务需求上。但是时至今日效用计算逐渐在数据中心开始占据一席之地。一些供应商向用户提供解决方案来帮助IT企业从商业服务器开始创建数据中心,诸如3Tera的AppLogic和Cohesive Flexible Technologies的Elastic Server都提供这种随需服务。Liquid Computing公司的LiquidQ也有类似的服务,能帮助企业将内存,I/0,存储和计算容量通过网络集成为一个虚拟的资源池来使用。

3.云计算的网络服务

网络服务与软件即服务(SaaS)是密切相关的,网络服务供应商提供API能帮助开发商通过网络拓展功能性,而不只是提供成熟的应用软件。他们的服务范围从提供分散的商业服务(诸如Strike Iron和Xignite )到涉及到Google Maps, ADP薪资处理流程,美国邮电服务,Bloomberg和常规的信用卡处理服务等的全套API服务。

4.平台即服务(Platform as a service)

平台即服务(Platform as a service)是软件即服务(SaaS)的变种,这种形式的云计算将开发环境作为服务来提供。你可以创建自己的应用软件在供应商的基础架构上运行,然后通过网络从供应商的服务器上传递给用户。比如乐高公司(Legos)就是这么做的。但这些服务会受到厂商设计和容量的限制,因此用户就没有足够的自由。代表公司包括Salesforce.com的Force.com和Coghead。

5.管理服务供应商(MSP)

管理服务是云计算*古老的形式之一,管理服务是面向IT厂商而并非*终用户的一种应用软件,诸如用于电子邮件的病毒扫描服务或者应用软件监控服务。由SecureWorks, IBM和Verizon公司提供的管理安全服务就归为此类,还有目前被Google收购的Postini以云为基础的反垃圾邮件服务。其他的产品还包含桌面系统管理服务,诸如CenterBeam和Everdream提供的产品。

6.服务商业平台

服务商业平台是软件即服务(SaaS)和管理服务供应商(MSP)的混合体,这种云计算服务提供了一种与用户相结合的服务采集器。在贸易领域中应用*为普遍,诸如费用管理系统能允许用户在用户设定的规格范围内从普通平台上订购与所要求的服务和价格相符的旅游产品或者秘书台服务,就好比一个自动化服务局,知名公司包括Rearden Commerce和Ariba。

7.网络集成

云基础服务的集成尚处于初始阶段。软件服务供应商OpSource目前推出了OpSource Services Bus,使用的就是被成为Boomi的云集成技术。软件即服务供应商Workday*近收购了这一领域中的另外一家公司CapeClear,这家ESB(企业服务总线)供应商主要从事B-TO-B商业模式的服务。Grand Central公司也致力于向用户提供集成解决方案,日前被Google所收购。

如今,云计算的运用还不是非常广泛,对于云计算更精确的描述可能是”天空运算”。同时,随着虚拟化和SOA在企业中的逐渐普及,这种想法也开始为大家所认同。可扩展的基础架构应该*终能将每一家企业都*为云的节点。这是个长期可发展的趋势,但是不可否认的是,云计算在很长的时期内还将是业界争论的难点之一。

转载于:https://blog.51cto.com/mooon/904854

Android中的权限机制

Android的权限管理遵循的是“*小特权原则”,即所有的Android应用程序都被赋予了*小权限。一个Android应用程序如果没有声明任何权限,就没有任何特权。

权限的历史

2013年,苹果公司发布IOS7系统。其中一项令开发者头疼的修改点:隐私中增加相册、录音等权限,App如需使用相应权限,需要申请并由用户同意(IOS7以前,可以直接访问相册),针对此点,很多App在首次启动时一通弹窗,申请各式各样的权限。

后来苹果为改善用户体验,在App Store审核时要求App必须在使用前一刻才能申请权限,有效改善了此类问题。比如一款直播App,当你启动App时并不需要相机、录音权限,等到你开播时才需要申请这两个权限。这一场景,其实就类似今天要提到的Android动态授权。

早期:无遮拦

Android6.0系统以前,在安装App前,会罗列出App申请的所有权限。如果继续安装,视为用户同意赋予App所需权限。这种机制是无遮拦的,在尝试安装App时,弹窗罗列了App申请的全部权限。只能对所需权限进行查看,无法拒*授权,可选择取消安装或继续安装。

这种方式,对于开发者*为友好,仅需在Manifest中配置App所需权限即可,代码就可以直接调用了。但是对于用户来说,这种方法存在*大的安全隐患。

%title插图%num

发展:第三方安全App

为解决部分敏感权限被不合理使用,国内部分公司的安全类App,开始监控应用获取手机敏感权限并做出提示。如360手机卫士、腾讯手机管家等产品,当监测到有App尝试使用短信权限、定位等敏感权限,会告知用户,并可以拒*赋予权限。刚开始,还比较顺利。但随着手机厂商逐渐开始修改ROM,第三方安全App的兼容、性能问题逐步爆发。

升级:厂商行动

再稍后一些,手机厂商开始行动,纷纷将第三方软件的权限提示功能直接做入ROM。并把安全作为产品的卖点进行打造。

%title插图%num

 

目前:谷歌升级权限管理

2015年推出的Android 6.0,加入了危险权限管理。因手机厂商对ROM的修改,部分6.0以上机器并不支持此项特性。到了此阶段,App需要在对权限代码进行修改后,才能正常使用对应权限。简单理解为3步:

  • 1、判断是否授权;
  • 2、如果未授权需申请权限,根据授权结果继续执行;
  • 3、已授权可以继续操作。

权限的使用和适配

零、权限的基础知识

Android系统基于Linux内核,系统中的权限分为3类:

  • Android手机所有者权限:这个和厂商相关,可以理解为系统权限。
  • Android ROOT权限:类似于Linux,这是Android系统中的*高权限。如果拥有该权限,就可以对Android系统中的任何文件、数据、资源进行任意操作。所谓“越狱”,就是令用户获得*高的ROOT权限。
  • Android应用程序权限:该权限在AndroidManifest文件中由程序开发者声明,在需要时由用户授权。

一、不适用动态权限

动态权限特性,仅从Android 6.0开始拥有,所以,可以简单粗暴的通过不提升targetSDK(targetSDK<23)的方式,便可不触发此特性。

如果不改变任何代码,直接将targetSDK提升到26,然后运行App,做同样操作时会发生异常甚至崩溃,产生这个崩溃的原因,是在Android 6.0及以上,未获取权限的情况下直接执行了需要权限的操作。

二、动态权限适配

1、在使用前权限前,检测权限

首先,我们需要判断自己是否拥有权限。判断时间点为执行需要权限的对应操作前。如我们在获取IMEI前,需要判断是否拥有PHONE_STATE权限。

我们可以调用ContextCompat.checkSelfPermission()方法检测授权状态,返回的结果为PackageManager中的两个常量:PERMISSION_GRANTED(已授权)和PERMISSION_DENIED(未授权)。

2、已授权的情况下,执行相应的操作

当已授权时,就可以执行原有的操作了。代码如下:

  1. // 检测PHONE_STATE 如果已授权
  2. if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
  3. //做你想做的
  4. }

3、未授权时,申请权限

如果App未获得授权,我们就需要向用户申请授权。可以调用requestPermissions()方法来请求授权。代码如下:

  1. // 检测PHONE_STATE 如果未授权
  2. if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
  3. //申请权限
  4. ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PERMISSIONS_REQUEST_PHONE_STATE)
  5. }

requestPermissions()中的第三个参数是一个int型请求码,方便回调处理。

调用申请授权方法后,ROM会调起一个系统级弹窗,这个dialog开发者无法定制。当用户点击同意后,系统会记录,下次再判断权限时就会返回已授权状态;当App卸载时,记录会被清除。

4、重写函数,处理授权弹窗的结果

直接在Activity或Fragment中重写onRequestPermissionsResult()函数,来处理权限申请结果。requestPermissions()的第三个参数,将在这里被用到。代码如下:

  1. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  2. if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
  3. if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  4. //todo
  5. } else {
  6. //todo
  7. }
  8. }
  9. }

一行代码搞定Android 6.0动态权限申请

1、前言
从Android 6.0(API 23)开始,对系统权限做了很大的改变。在之前用户安装APP前,只是把APP需要使用的权限列出来给用户告知一下,APP安装后都可以访问这些权限。从6.0开始,一些敏感权限,需要在使用时动态申请,并且用户可以选择拒*授权访问这些权限,已授予过的权限,用户也可以去APP设置页面去关闭授权。这对用户来说提高了安全性,可以防止一些应用恶意访问用户数据,但是对于开发来说,也增加了不少工作量,这块不做适配处理的话,APP在访问权限的时候会容易crash。

2、权限等级和权限组
权限主要分为normal、dangerous、signature和signatureOrSystem四个等级,常规情况下我们只需要了解前两种,即正常权限和危险权限。

2.1、正常权限
正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。应用声明其需要正常权限,系统会自动授予该权限。例如设置时区,只要应用声明过权限,系统就直接授予应用此权限。下面是截止到API 23的普通权限(需*访问)

%title插图%num

2.2、危险权限
危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如读取用户联系人,在6.0以上系统中,需要在运行时明确向用户申请权限。

2.3、权限组
系统根据权限用途又定义了权限组,每个权限都可属于一个权限组,每个权限组可以包含多个权限。例如联系人权限组,包含读取联系人、修改联系人和获取账户三个权限。
* 如果应用申请访问一个危险权限,而此应用目前没有对应的权限组内的任何权限,系统会弹窗提示用户要访问的权限组(注意不是权限)。例如无论你申请READ_CONTACTS还是WRITE_CONTACTS,都是提示应用需要访问联系人信息。
* 如果用户申请访问一个危险权限,而应用已经授权同权限组的其他权限,则系统会直接授权,不会再与用户有交互。例如应用已经请求并授予了READ_CONTACTS权限,那么当应用申请WRITE_CONTACTS时,系统会立即授予该权限。下面为危险权限和权限组:
%title插图%num

3、运行时请求权限
关于运行时请求权限,官网介绍的很清楚,也有很多其他文章介绍,这里只是简单罗列一下。

3.1、检查权限
应用每次需要危险权限时,都要判断应用目前是否有该权限。兼容库中已经做了封装,只需要通过下面代码即可:

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);

如果有权限则返回PackageManager.PERMISSION_GRANTED,否则返回PackageManager。PERMISSION_DENIED。

3.2、请求权限
当应用需要某个权限时,可以申请获取权限,这时会有弹出一个系统标准Dialog提示申请权限,此Diolog不能定制,用户同意或者拒*后会通过方法onRequestPermissionsResult()返回结果。当用户拒*过此权限申请时,再次申请Dialog上可以勾选不再提示,这种情况下,以后再申请权限不会弹Dialog直接返回拒*。所以一些依赖某些敏感权限的应用,需要自己去处理,向用户解释 为什么需要此权限,说服用户授予权限。请求权限代码如下:

ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE);

3.3、处理权限请求响应
当用户处理权限请求后,系统会回调申请权限的Activity的onRequestPermissionsResult()方法,只需要覆盖此方法,就能获得返回结果

@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the
// contacts-related task you need to do.

} else {

// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}

3.4、考虑使用intent
有很多权限操作可以考虑调用其他应用,这样的话当前应用就不需要申请权限。例如想要获取相机照相,可以通过ACTION_IMAGE_CAPTURE唤起相机应用去完成,相机应用会把照片返回。同样拨打电话、访问联系人,都可以考虑使用类似方法。相比较其他应用,这类专门的应用做一些操作更容易让用户接受。

4、 关于国产机6.0以下系统
部分国产厂商定制了系统(例如小米、华为),在6.0以下系统就可以单独控制权限。但是通常它们处理的不够彻底,代码中判断是否授权的时候,返回的是已经授权。而真正去做操作的时候,却会因为没有权限导致应用crash。例如我曾遇到过的场景:
* 访问联系人,可以拿到Cursor对象,但是cursor.moveToFirst()会返回false。
* 访问摄像头时,获取到的Camera对象为空

所以在低版本手机上,不要以为拥有系统授权就万事大吉了,一定要多加条件判读和测试。

5、PermissionGrantor,一行代码搞定动态权限申请。
上面运行时请求权限中,我们看到了权限申请依赖于Activity和Fragment,和startActivityForResult()方法的使用类似,必须依赖于Activity和Fragment的回调方法。正常情况下还能满足需求,可是当申请的权限的代码在一个独立的模块中时,例如我封装了一个UI控件,控件中某个操作需要申请权限,或者项目采用了MVVM框架,需要在一些view类或者model类中申请权限,这是处理起来就会很麻烦。
我在自己代码中就遇到类似情况,后面我采用了使用一个单独的Activity来申请权限,通过回调的方式通知业务层授权结果。感觉使用起来挺方便,就把它放到maven仓库中了,项目中通过加入如下依赖即可。

compile ‘com.github.dfqin:grantor:2.1.0’

5.1 PermissionGrantor使用
申请权限很简单,只需要下面一句话即可。

PermissionsUtil.requestPermission(Activity activity, PermissionListener listener,
String[] permissions);

下面是一个申请摄像头的例子:

private void requestCemera() {
if (PermissionsUtil.hasPermission(this, Manifest.permission.CAMERA)) {
//有访问摄像头的权限
} else {
PermissionsUtil.requestPermission(this, new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
//用户授予了访问摄像头的权限
}

@Override
public void permissionDenied(@NonNull String[] permissions) {
//用户拒*了访问摄像头的申请
}
}, new String[]{Manifest.permission.CAMERA});
}
}

PermissionsUtil.requestPermission还有两个重载的实现。用户拒*授权时,会有一个默认Dialog提示用户开通权限。这个Dialog的内容可以定制,也可以不显示此Dialog

能否利用Hadoop搭建完整的云计算平台

Hadoop并不完全代表云计算,所以,要用Hadoop搭建完整的云计算平台,答案是不够。我们常说云计算,实际上还是通过计算机的大规模或者 说海量处理来为生活中各式各样的人和各行各业服务——所以,核心在“服务”。关于服务,展开来就是常用的那3种(也是事实上的标 准):SaaS,PaaS,IaaS。对云计算来说,公有和私有,虚拟和存储,这其实是相对讨论的核心。

回头说Hadoop。在Google三大论文的直接刺激下,Hadoop社区兴起,而在众多的开源实现中,Hadoop(主项目)可以说是所有已知云计算方面开源项目的一个Top项目。

云计算中有哪些构件?发展到目前的技术与规模,并没有一个确切的定论,今天的说的话明天可能就不一样了。但对Hadoop来说,实现了的部分,就是大部分企业在不断发展中所遇到的大部分问题。直接上图:
%title插图%num

从整体生态系统的角度,从底层存储,到中间的计算模型和框架,再到上层的逻辑处理和流、显示,都有相应开源的实现。这就是你说的构件了。

包括我们看到的Hadoop2.0中,引入的新的处理框架,Spark,Storm,YARN(取代MR),都是Hadoop生态系统的完善与实现。

Hadoop实现的是在简易硬件的基础上进行尽量高可用性海量计算与处理的中上层模型。Hadoop处理了存储(也只是一部分),虚拟化是没有涉 及的,而底层硬件Hadoop也是不涉及的,不管是Hadoop还是其他的项目,只是在软件的层面想通过纵向或者横向的拓展解决所有的问题是不现实的。 Hadoop在硬件这方面,只是在实现中预留或者接入硬件特性,也就是在虚拟化这方面Hadoop只是个“APP”,不是“始作俑者”(用词不当了)。

那么,完整的云计算平台呢?

按照企业级来说,是要看具体的企业方向和企业类型的,包括IBM和VMware都有提供不同的解决方案。大致上一定是由单点–>集群 –>多层(准分布式)–>硬件–>分布式(地域分布)来解决的。具体到Hadoop体系的技术,直接去对应上图就好了。

从云计算这个概念出现到今天,资料可以说“浩如烟海”了,但很多资料只是互相复制黏贴,并没有说到云计算的核心。我想提出的一个观点是,完整的云计算平台,依赖的是业务,提供的是存储与支持。

没有业务需求而是照搬网上的资料或者自认为“活用”了某些技术,都可能只是“娱人娱己”。我们看一下互联网负载均衡技术是如何发展的就就更容易理解云计算:

客户端缓存–>CDN缓存–>Apache&Nginx静态页面缓存–>PHP和Java动态内存 –>Memcache&Other Nosql–>Mysql&Oracle–>HDFS&Other Big Table

从技术的角度看,所有问题解决起来都是层次化的(大家肯定都有写Demo吧),都是根据不同的需求引入不同的技术,在单层单点乃至集群都无法解决 问题的时候,新的计算框架,云计算与网格计算乃至动画需要的大规模渲染都在需要的时候顺理成章的引入。总之,完整的云计算平台,对于不同的公司业务都是不 同的,拿腾讯来说,平台的组件多如牛毛,“平台”只是提供*基础的服务:存储与支持,其他的都需要业务根据自身的特点在其上进行构建(相信大公司都是有自 己的完整方案的,这里我就不能再说了……),至于提高什么样级别的这种“服务”,就要看公司的业务规模,需要支撑的体系,乃至公司的决策战略了等等

原文链接:
http://www.open-open.com/solution/view/1426725577820

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速