Swift可以再类型后面加一个?来将变量声明为optional(随意的)。如果不是Optional的变量,那么它就必须有值,而没有值发话,我们使用Optional并且将它设置为nil来表示没有值。

1
2
3
var num:Int?
num = nil
num = 3

Optional Value就像一个盒子,盒子可能装着实际的值,可能声明都没装。

1
2
3
4
5
6
var num:Int?=3	// 声明一个Int的Optianal,并将其设为3
if let n = num {
// hava a num
} else {
// no num
}

使用场景

1
foo?.somemethod()

数据持久化的方法有:

  • 保存在硬盘或闪存上
  • 保存在计算机内存中
  • 保存在数据库中
  • 保存在cookie或会话中

将数据写入文件

1
2
3
4
5
6
7
8
9
10
// weite.js
var fs = require('fs'),
data = "Some data I want to write to a file.";
fs.writeFile('file.txt',data,function(err){
if (!err) {
console.log("Wrote data to file.txt.");
} else {
throw err;
}
});

注意:

  1. 如果文件不存在,writeFile方法也创建文件
  2. 文件默认写入脚本运行位置,也可以指定完整路径
  3. 可能的错误包括文件不存在或者没有读取文件的权限

从文件读取数据

1
2
3
4
5
6
7
8
9
// read.js
var fs = require('fs');
fs.readFile('file.txt','utf8',function(err,data){
if (!err) {
console.log(data);
}else{
throw err;
}
});

环境变量

设置环境变量
windows:

1
SET SOMETHING='12345678'

UNIX:

1
var something = process.env.SOMETHING

可以再node中访问process.env.SOMETHING

使用数据库

NoSQL数据库

  • Cassandra
  • Redis
  • Memcached
  • MongoDB
  • Hadoop

在Node.js中使用MongoDB

MongoDB是面向文档的数据库,它不遵照将关系数据连接在一起的关系模型,它可执行关系数据库的大多数功能并且旨在提供高度的可用性和可扩展性。
CRUD指Create、Read、Update、Delete

安装MongiDB

可以到MongoDB官网获得对应平台的安装文件。
MongoDB有很多GUI支持,OSX可以使用MongoHub;Windows,可以使用Monogo VUE,它是功能受限的免费版,同事需要.NET Framework支持;Linux上可以使用JMongoBrowser,它是基于Java客户端,需要Java运行环境。

连接MongoDB

Mongoose是Node.js中一个功能齐备的第三方模块,用于处理MongoDB。将Mongoose模块加入到项目中,并在package.json文件中将其作为依赖模块包含进来:

1
2
3
4
5
6
7
{
"name":"your-application",
"version":"0.0.1",
"dependcies":{
"mongoose":">= 2.3.1"
}
}

运行npm install
并在应用程序文件中请求它var mongoose = require('mongoose');
之后连接并使用它mongoose.connect('mongodb://localhost/your_database');.

定义文档

MongoDB中,没有关系数据库中表的概念,M哦你goDB围绕着文档的思想来组织数据。
通过Mongoose模块在MongoDB中定义一个文档:通过Mongoose提供的Schema接口定义,然后声明属性。Mongoose可声明的类型如下:

  • String(字符串)
  • Number(数值)
  • Date(日期)
  • Boolean(布尔值)
  • Buffer(缓存)
  • ObjectID(对象ID)
  • Mixed(混合)
  • Array(数组)
    对于task模型而言,只需要一个属性
1
2
3
4
5
6
var Schema = mongoose.Schema,
ObjectId = Shema.ObjectId;
var Task = new Schema({
task:String
});
var Task = mongoose.model('Task',Task);

将Twitter Bootstrap包含进来

views/layout.jade包含如下内容

1
2
3
4
5
6
html 
head
title=title
link(rel='stylesheet',href='http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css')
body
section.container!=body

数据类

  • Bimp
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
public class Bimp {
public static int max = 0;
public static boolean act_bool = true;
public static List<Bitmap> bmp = new ArrayList<Bitmap>();
// 图片的存放地址
public static List<String> drr = new ArrayList<String>();
// 用于压缩图片
public static Bitmap revitionImageSize(String path)throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
new File(path)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
int i = 0;
Bitmap bitmap = null;
while (true) {
if ((options.outWidth >> i <= 1000)
&& (options.outHeight >> i <= 1000)) {
in = new BufferedInputStream(
new FileInputStream(new File(path)));
options.inSampleSize = (int) Math.pow(2.0D, i);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(in, null, options);
break;
}
i++;
}
return bitmap;
}
}

工具类

  • BitmapCache类
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class BitmapCache {
public final String TAG = getClass().getSimpleName();
public Handle h = new Handle();
private HashMap<String,SoftReference<Bitmap>> imageCache = new HashMap<String,SoftReference<Bitmap>>();
public void put(String path,Bitmap bmp) {
if(!TextUtils.isEmpty(path) && bmp != null) {
imageCache.put(path, new SoftReference<Bitmap>(bmp));
}
}
public void displayBmp(final ImageView iv, final String thumbPath, final String sourcePath, final ImageCallback call ballback) {
if (TextUtils.isEmpty(thumbPath) && TextUtils.isEmpty(sourcePath)) {
Log.e(TAG, "no paths pass in");
return;
}
final String path;
final boolean isThumbPath;
if (!TextUtils.isEmpty(thumbPath)) {
path = thumbPath;
isThumbPath = true;
}else if (!TextUtils.isEmpty(sourcePath)) {
path = sourcePath;
isThumbPath = false;
}else {
return;
}
// 缓存中是否有该图片
if(imageCache.containsKey(path)){
SoftReference<Bitmap> reference = imageCache.get(path);
if (bmp != null) {
if (callback != null) {
callback.imageLoad(iv, bmp ,sourcePath);
}
iv.setImageBitmap(bmp);
Log.d(TAG,"hit cache");
return;
}
}
iv.setImageBitmap(null);
new Thread() {
Bitmap thumb;
public void run(){
try {
if (isThumbPath) {
thumb = BitmapFactory.decodeFile(thumbPath);
if (thumb == null) {
thumb = revitionImageSize(sourcePath);
} else {
thumb = revitionImageSize(thumbPath);
}
} catch (Exception e){

}
if (thumb == null) {
thumb = revitionImageSize(sourcePath);
}
put(path,thumb);
if(callback != null){
h.post(new Runnable(){
@Override
public void run() {
callback.imageLoad(iv, thumb, sourcePath);
}
});
}
}
}.strat();
}

public Bitmap revitionImageSize(String path) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
new File(path)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
int i = 0;
Bitmap bitmap = null;
while (true) {
if ((options.outWidth >> i <= 256)
&& (options.outHeight >> i <= 256)) {
in = new BufferedInputStream(
new FileInputStream(new File(path)));
options.inSampleSize = (int) Math.pow(2.0D, i);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(in, null, options);
break;
}
i += 1;
}
return bitmap;
}

public interface ImageCallback {
public void imageLoad(ImageView imageView, Bitmap bitmap,
Object... params);
}
}
  • AlbumHelper
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
public class AlbumHelper {
private final String TAG = getClass().getSimpleName();
private Context context;
private ContentResolver cr;

// 缩略图列表
public HashMap<String, String> thumbnailList = new HashMap<String, String>();
// 专辑列表
private List<HashMap<String, String>> albumList = new ArrayList<HashMap<String, String>>();
private HashMap<String, ImageBucket> bucketList = new HashMap<String, ImageBucket>();

private static AlbumHelper instance;

private AlbumHelper() {
}

public static AlbumHelper getHelper() {
if (instance == null) {
instance = new AlbumHelper();
}
return instance;
}

/**
* 初始化
*
* @param context
*/
public void init(Context context) {
if (this.context == null) {
this.context = context;
cr = context.getContentResolver();
}
}

/**
* 得到缩略图
*/
private void getThumbnail() {
String[] projection = { Thumbnails._ID, Thumbnails.IMAGE_ID,
Thumbnails.DATA };
Cursor cursor = cr.query(Thumbnails.EXTERNAL_CONTENT_URI, projection,
null, null, null);
getThumbnailColumnData(cursor);
}

/**
* 从数据库中得到缩略图
*
* @param cur
*/
private void getThumbnailColumnData(Cursor cur) {
if (cur.moveToFirst()) {
int _id;
int image_id;
String image_path;
int _idColumn = cur.getColumnIndex(Thumbnails._ID);
int image_idColumn = cur.getColumnIndex(Thumbnails.IMAGE_ID);
int dataColumn = cur.getColumnIndex(Thumbnails.DATA);

do {
_id = cur.getInt(_idColumn);
image_id = cur.getInt(image_idColumn);
image_path = cur.getString(dataColumn);
thumbnailList.put("" + image_id, image_path);
} while (cur.moveToNext());
}
}

/**
* 得到原图
*/
private void getAlbum() {
String[] projection = { Albums._ID, Albums.ALBUM, Albums.ALBUM_ART,
Albums.ALBUM_KEY, Albums.ARTIST, Albums.NUMBER_OF_SONGS };
Cursor cursor = cr.query(Albums.EXTERNAL_CONTENT_URI, projection, null,
null, null);
getAlbumColumnData(cursor);

}

/**
* 从本地数据库中得到原图
*
* @param cur
*/
private void getAlbumColumnData(Cursor cur) {
if (cur.moveToFirst()) {
int _id;
String album;
String albumArt;
String albumKey;
String artist;
int numOfSongs;

int _idColumn = cur.getColumnIndex(Albums._ID);
int albumColumn = cur.getColumnIndex(Albums.ALBUM);
int albumArtColumn = cur.getColumnIndex(Albums.ALBUM_ART);
int albumKeyColumn = cur.getColumnIndex(Albums.ALBUM_KEY);
int artistColumn = cur.getColumnIndex(Albums.ARTIST);
int numOfSongsColumn = cur.getColumnIndex(Albums.NUMBER_OF_SONGS);

do {
_id = cur.getInt(_idColumn);
album = cur.getString(albumColumn);
albumArt = cur.getString(albumArtColumn);
albumKey = cur.getString(albumKeyColumn);
artist = cur.getString(artistColumn);
numOfSongs = cur.getInt(numOfSongsColumn);

Log.i(TAG, _id + " album:" + album + " albumArt:" + albumArt
+ "albumKey: " + albumKey + " artist: " + artist
+ " numOfSongs: " + numOfSongs + "---");
HashMap<String, String> hash = new HashMap<String, String>();
hash.put("_id", _id + "");
hash.put("album", album);
hash.put("albumArt", albumArt);
hash.put("albumKey", albumKey);
hash.put("artist", artist);
hash.put("numOfSongs", numOfSongs + "");
albumList.add(hash);
} while (cur.moveToNext());
}
}

/**
* 是否创建了图片集
*/
private boolean hasBuildImagesBucketList = false;

/**
* 得到图片集
*/
private void buildImagesBucketList() {
long startTime = System.currentTimeMillis();

// 构造缩略图索引
getThumbnail();

// 构造相册索引
String columns[] = new String[] { Media._ID, Media.BUCKET_ID,
Media.PICASA_ID, Media.DATA, Media.DISPLAY_NAME, Media.TITLE,
Media.SIZE, Media.BUCKET_DISPLAY_NAME };
// 得到一个游标
Cursor cur = cr.query(Media.EXTERNAL_CONTENT_URI, columns, null, null,
null);
if (cur.moveToFirst()) {
// 获取指定列的索引
int photoIDIndex = cur.getColumnIndexOrThrow(Media._ID);
int photoPathIndex = cur.getColumnIndexOrThrow(Media.DATA);
int photoNameIndex = cur.getColumnIndexOrThrow(Media.DISPLAY_NAME);
int photoTitleIndex = cur.getColumnIndexOrThrow(Media.TITLE);
int photoSizeIndex = cur.getColumnIndexOrThrow(Media.SIZE);
int bucketDisplayNameIndex = cur
.getColumnIndexOrThrow(Media.BUCKET_DISPLAY_NAME);
int bucketIdIndex = cur.getColumnIndexOrThrow(Media.BUCKET_ID);
int picasaIdIndex = cur.getColumnIndexOrThrow(Media.PICASA_ID);
// 获取图片总数
int totalNum = cur.getCount();

do {
String _id = cur.getString(photoIDIndex);
String name = cur.getString(photoNameIndex);
String path = cur.getString(photoPathIndex);
String title = cur.getString(photoTitleIndex);
String size = cur.getString(photoSizeIndex);
String bucketName = cur.getString(bucketDisplayNameIndex);
String bucketId = cur.getString(bucketIdIndex);
String picasaId = cur.getString(picasaIdIndex);

Log.i(TAG, _id + ", bucketId: " + bucketId + ", picasaId: "
+ picasaId + " name:" + name + " path:" + path
+ " title: " + title + " size: " + size + " bucket: "
+ bucketName + "---");

ImageBucket bucket = bucketList.get(bucketId);
if (bucket == null) {
bucket = new ImageBucket();
bucketList.put(bucketId, bucket);
bucket.imageList = new ArrayList<ImageItem>();
bucket.bucketName = bucketName;
}
bucket.count++;
ImageItem imageItem = new ImageItem();
imageItem.imageId = _id;
imageItem.imagePath = path;
imageItem.thumbnailPath = thumbnailList.get(_id);
bucket.imageList.add(imageItem);

} while (cur.moveToNext());
}
// Interator为迭代器,Entry为Map接口
// 遍历所有图片
Iterator<Entry<String, ImageBucket>> itr = bucketList.entrySet()
.iterator();
while (itr.hasNext()) {
Map.Entry<String, ImageBucket> entry = (Map.Entry<String, ImageBucket>) itr
.next();
ImageBucket bucket = entry.getValue();
Log.d(TAG, entry.getKey() + ", " + bucket.bucketName + ", "
+ bucket.count + " ---------- ");
for (int i = 0; i < bucket.imageList.size(); ++i) {
ImageItem image = bucket.imageList.get(i);
Log.d(TAG, "----- " + image.imageId + ", " + image.imagePath
+ ", " + image.thumbnailPath);
}
}
hasBuildImagesBucketList = true;
long endTime = System.currentTimeMillis();
Log.d(TAG, "use time: " + (endTime - startTime) + " ms");
}

/**
* 得到图片集
*
* @param refresh
* @return
*/
public List<ImageBucket> getImagesBucketList(boolean refresh) {
if (refresh || (!refresh && !hasBuildImagesBucketList)) {
buildImagesBucketList();
}
List<ImageBucket> tmpList = new ArrayList<ImageBucket>();
Iterator<Entry<String, ImageBucket>> itr = bucketList.entrySet()
.iterator();
while (itr.hasNext()) {
Map.Entry<String, ImageBucket> entry = (Map.Entry<String, ImageBucket>) itr
.next();
tmpList.add(entry.getValue());
}
return tmpList;
}

/**
* 根据图片的_ID得到原始图像路径
*
* @param image_id
* @return
*/
public String getOriginalImagePath(String image_id) {
String path = null;
Log.i(TAG, "---(^o^)----" + image_id);
String[] projection = { Media._ID, Media.DATA };
Cursor cursor = cr.query(Media.EXTERNAL_CONTENT_URI, projection,
Media._ID + "=" + image_id, null, null);
if (cursor != null) {
cursor.moveToFirst();
path = cursor.getString(cursor.getColumnIndex(Media.DATA));
}
return path;
}
}

layout

相册选取layout

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
33
34
35
36
37
38
39
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="# f1eff5"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="# ff495a" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="相册"
android:textColor="# ffffff"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:textColor="@drawable/text_while"
android:text="取消"
android:textSize="20sp" />
</RelativeLayout>
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:horizontalSpacing="20dp"
android:numColumns="2"
android:scrollbars="none"
android:verticalSpacing="20dp" >
</GridView>
</LinearLayout>
  • 图片选取layout
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
33
34
35
36
37
38
39
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="# f1eff5"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="# ff495a" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="相册"
android:textColor="# ffffff"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:textColor="@drawable/text_while"
android:text="取消"
android:textSize="20sp" />
</RelativeLayout>
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:horizontalSpacing="20dp"
android:numColumns="2"
android:scrollbars="none"
android:verticalSpacing="20dp" >
</GridView>
</LinearLayout>
  • 图片预览layout
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
33
34
35
36
37
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
<RelativeLayout
android:id="@+id/photo_relativeLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true" >
<Button
android:id="@+id/photo_bt_exit"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/bt_quxiao" />
<Button
android:id="@+id/photo_bt_del"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@drawable/bt_shanchu" />
<Button
android:id="@+id/photo_bt_enter"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/bt_queding" />
</RelativeLayout>
</RelativeLayout>

除了揭幕战,今天又真真的熬完了整整一场比赛的直播。开赛前就冥冥感觉,这场不一般,当然我不是马后炮的证明我猜到了大胜,赛前我的预想只是净胜2球,德意志已经超过我的想象。其实比,大胜更让我欣喜的是,米洛进球了。那一刻,真的想流泪,即使段暄还在感叹节奏的突变,与接二连三的进球,人们视乎忘了,这个德国人破纪录了。
没有欢呼,没有庆贺,没有空翻,一切平平淡淡。就像克洛泽一样,一个平凡的不能再平凡的球员,没错,在很多定义上他都算不上球星。他不张扬,个性内敛和谦逊,小时候优良的家境和艺术教育的烘托使得他跟一般的球员在性格上可以被归属为文艺派。
克洛泽从未在联赛中大杀四方,也没有在世界杯上君临天下,他总是在适当的时候,出现在适当的位置,做了适当的事情。这就是德国人的冷静、铁血、严谨,这是与生俱来的天性。他不是足球天才,23岁的时候甚至还是业余球球,这个岁数的梅西已经功成名就。
不是每个人都能成为字母罗、内马尔或者梅西,但每个人都可以成为克洛泽————或者说,成为这个时空中、这番命运下那个最好的自己。

02年世界杯的时候,那个时候我还懵懵懂懂,决赛日,我和老爸在电视前,我穿着我新买不久的巴西队服,看着除了巴西队不怎么熟悉的面孔,为罗纳尔多的进球欢呼雀跃,但是那场比赛,却让我喜欢上了,卡恩和金发碧眼的克洛泽,甚至我自己都不知道缘由。
06年,金色轰炸机克林斯曼职教德国,那届的德国打的真是漂亮,不知道那一届诞生了多少德国脑残粉。点球救主的莱曼,小猪施魏因斯泰格,已经屈居二线的卡恩,大着石膏扔界外球的拉姆,还有些青涩的波多尔斯基,还有巴拉克,还有克洛泽。那一届德国踢得那么好,那么漂亮,还是输给了亚平宁骑士,防守至上的意大利。至今,我还记恨那支冠军,马特拉齐的咒骂,齐祖的惨淡谢幕与大力神杯擦肩而过,更可恨的是他们淘汰了德国,那支最美的德国。
10年,德国新人辈出,诺伊尔、厄齐尔、巴阿滕、还有神奇小子穆勒。可惜巴拉克,赛前的伤退,让这个德国人永远的告别了世界杯。我这届德国一如既往的强,可惜既生瑜何生亮,如日中天的西班牙在那个时空,仿佛不可战胜。
02年,我们输给了天赋异禀的巴西,06年,我们输给了沉稳的意大利,10年,我们输给了不可战胜的西班牙。14年,我们离冠军只差一场胜利,加油,德意志。

1
2
3
4
5
6
7
8
9
node
var url = require('url')
var requestURL = 'http://example.com:1234/pathname?query=string# hash'
// 获取主机名
url.parse(requestURL).hostname
// 获取路径端口
url.parse(requestURL).port
// 获取路径名
url.parse(requestURL).pathname

权限

1
2
3
4
5
6
7
8
<!-- 发送消息 -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- 阅读消息 -->
<uses-permission android:name="android.permission.READ_SMS" />
<!-- 写入消息 -->
<uses-permission android:name="android.permission.WRITE_SMS" />
<!-- 接收消息 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />

工具类

  • Column
    用于管理字段
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
33
34
35
36
37
38
39
40
41
42
43
44
public class Column {
// 约束
public static enum Constraint {
UNIQUE("UNIQUE"), NOT("NOT"), NULL("NULL"), CHECK("CHECK"), FOREIGN_KEY(
"FOREIGN KEY"), PRIMARY_KYE("PRIMARY KEY");
private String value;

private Constraint(String value) {
this.value = value;
}

@Override
public String toString() {
return value;
}
}

// 数据类型
public static enum DataType {
NULL, INTEGER, REAL, TEXT, BLOB
}

private String mColumnName;
private Constraint mConstraint;
private DataType mDataType;

public Column(String columnName, Constraint constraint, DataType dataType) {
mColumnName = columnName;
mConstraint = constraint;
mDataType = dataType;
}

public String getColumnName() {
return mColumnName;
}

public Constraint getConstraint() {
return mConstraint;
}

public DataType getDataType() {
return mDataType;
}
}
  • SQLiteTable
    用于表管理
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class SQLiteTable {
String mTableName;
ArrayList<Column> mColumnsDefinitions = new ArrayList<Column>();

public String getTableName() {
return mTableName;
}

// 自动添加主键_ID
public SQLiteTable(String tableName) {
mTableName = tableName;
mColumnsDefinitions.add(new Column(BaseColumns._ID,
Column.Constraint.PRIMARY_KYE, Column.DataType.INTEGER));
}

public SQLiteTable addColumn(Column columnsDefinition) {
mColumnsDefinitions.add(columnsDefinition);
return this;
}

public SQLiteTable addColumn(String columnName, Column.DataType dataType) {
mColumnsDefinitions.add(new Column(columnName, null, dataType));
return this;
}

public SQLiteTable addColumn(String columnName,
Column.Constraint constraint, Column.DataType dataType) {
mColumnsDefinitions.add(new Column(columnName, constraint, dataType));
return this;
}

// 在SQLite中创建本表
public void create(SQLiteDatabase db) {
String formatter = " %s";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("CREATE TABLE IF NOT EXISTS ");
stringBuilder.append(mTableName);
stringBuilder.append("(");
int columnCount = mColumnsDefinitions.size();
int index = 0;
for (Column columnsDefinition : mColumnsDefinitions) {
stringBuilder.append(columnsDefinition.getColumnName()).append(
String.format(formatter, columnsDefinition.getDataType()
.name()));
Column.Constraint constraint = columnsDefinition.getConstraint();

if (constraint != null) {
stringBuilder.append(String.format(formatter,
constraint.toString()));
}
if (index < columnCount - 1) {
stringBuilder.append(",");
}
index++;
}
stringBuilder.append(");");
db.execSQL(stringBuilder.toString());
}

// 在SQLite中删除本表
public void delete(final SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + mTableName);
}
}

数据库操作类

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public abstract class BaseDataHelper {
private Context mContext;

public BaseDataHelper(Context context) {
mContext = context;
}

public Context getContext() {
return mContext;
}

protected abstract Uri getContentUri();

public void notifyChange() {
mContext.getContentResolver().notifyChange(getContentUri(), null);
}

protected final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
return mContext.getContentResolver().query(uri, projection, selection,
selectionArgs, sortOrder);
}

protected final Cursor query(String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
return mContext.getContentResolver().query(getContentUri(), projection,
selection, selectionArgs, sortOrder);
}

protected final Uri insert(ContentValues values) {
return mContext.getContentResolver().insert(getContentUri(), values);
}

protected final int bulkInsert(ContentValues[] values) {
return mContext.getContentResolver()
.bulkInsert(getContentUri(), values);
}

protected final int update(ContentValues values, String where,
String[] whereArgs) {
return mContext.getContentResolver().update(getContentUri(), values,
where, whereArgs);
}

protected final int delete(Uri uri, String selection, String[] selectionArgs) {
return mContext.getContentResolver().delete(getContentUri(), selection,
selectionArgs);
}

protected final Cursor getList(String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
return mContext.getContentResolver().query(getContentUri(), projection,
selection, selectionArgs, sortOrder);
}

public CursorLoader getCursorLoader(Context context) {
return getCursorLoader(context, null, null, null, null);
}

protected final CursorLoader getCursorLoader(Context context,
String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
return new CursorLoader(context, getContentUri(), projection,
selection, selectionArgs, sortOrder);
}
}

  1. Add column
1
ALTER TABLE {tableName} ADD COLUMN COLNew {type};

2.Delete column,Rename column
sqlite3不允许指直接delete,rename只能进行以下操作

1
2
create table temp(id integer PRIMARY KEY,code varchar(255));
insert into temp(id,code) select id ,code from t;

3.Rename table

1
alter table foo rename to bar

4.Copy data from one sqlite file to another

1
2
attach 'database2file' as db2;
insert into TANLENAME select * from db2.TANLENAME;

5.导出sql

1
2
3
sqlite3. data.db
>.output dd.sql
>.dump

6.导入

1
2
sqlite3 mydb.db
>.read dd.sql

7.释放空间

1
vacuum

一些SQLite命令

  • database 列出数据库文件名
  • tables ?PATTERN? 列出?PATTERN?匹配的表名
  • import FILE TABLE 将文件中的数据导入表中
  • dump ?TABLE? 生成形成数据表的SQL脚本
  • output FILENAME 将输出导入到指定的文件中
  • output stdout 将输出打印到屏幕
  • mode MODE ?TABLE? 设置数据输出模式(csv,html,tcl…)
  • nullvalue STRING 用指定的串代替输出的NULL串
  • read FILENAME 指定指定文件中的SQL语句
  • schema ?STRING? 打印创建数据库表的SQL语句
  • separator STRING 用指定的字符串代替字段分隔符
  • show 打印所有SQLite环境变量的设置
  • quite 推出命令行接口

使用

DrawerLayout类在Support Library里,有android-support-v4.jar这个包即可

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
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />


<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="# 111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>

</RelativeLayout>

  1. Uri
    通用资源标志符(Universal Resource Ident,简称”URI”)
    Uri代表要操作的数据,Android上可用的每种资源——图片、视频等资源都可以用Uri表示
    URI一般分为三个部分组成:访问资源的命名机制存放资源的主机名,资源自身的名字,由路径表示

Android的Uri由以下三部分组成:”content://“、数据的路径、标示ID(可选)
如:

  • 所有联系人的Uri:content://contacts/people
  • 某个联系人的Uri:content://contacts/people/5
  • 所有图片Uri:content://media/external
  • 某个图片的Uri:content://media/external/images/media/4
  1. UriMatcher
    UriMatcher类主要用于匹配Uri
    使用方法如下,初始化:
1
UriMathcer matcher = new UriMatcher(UriMatcher.NO_MATCH);

第二步注册需要的Ur:

1
2
matcher.addURI("com.zoe.blog","people",PEOPLE);
matcher.addURI("com.zoe.blog", "person/# ", PEOPLE_ID);

第三部,与已经注册的Uri进行匹配:

1
2
3
4
5
6
7
8
9
10
11
Uri uri = Uri.parse("content://" + "com.zoe.blog" + "/people");
int match = matcher.match(uri);
switch(match)
{
case PEOPLE:
return "vnd.android.cursor.dir/people";
case PEOPLE_ID:
return "vnd.android.cursor.item/people";
default:
return null;
}

match方法匹配后会返回一个匹配码Code,即在使用注册方法addURI时传入的第三个参数。

  • 常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
  • # 号为通配符
  • *号为任意字符
  1. CententUris
    ContentUris类用于获取Uri路径后面的ID部分
1
2
3
4
5
Uri uri = Uri.parse("content://com.zoe.demo/people");
Uri resultUri = ContentUris.withAppendedId(uri,10);
//resultUri为:content://com.zoe.demo/people/10
ling id = ContentUris.parseId(uri);
//id = 10