Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] authored and [email protected] committed Feb 23, 2014
2 parents 968cba6 + ab23823 commit 28fe0f7
Show file tree
Hide file tree
Showing 5 changed files with 466 additions and 67 deletions.
108 changes: 41 additions & 67 deletions day02Android数据存储.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ day02Android数据存储
===

1. Android数据存储的几种形式
1. File

- 内部存储
通过`mContext.getFilesDir()`来得到`data/data/包名/Fil`e目录
- SD卡
```java
TextView tv = (TextView) findViewById(R.id.tv_sdsize);
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
long sizeAvailSize = blockSize * availableBlocks;
String str = Formatter.formatFileSize(this, sizeAvailSize);
tv.setText(str);
```
2. SharedPreferences
1. Internal Storage
Store private data on the device memory.
通过`mContext.getFilesDir()`来得到`data/data/包名/File`目录
2. External Storage
Store public data on the shared external storage.
```java
TextView tv = (TextView) findViewById(R.id.tv_sdsize);
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
long sizeAvailSize = blockSize * availableBlocks;
String str = Formatter.formatFileSize(this, sizeAvailSize);
tv.setText(str);
```
3. SharedPreferences
Store private primitive data in key-value pairs.
会在`data/data/包名/shared_prefes`里面去创建相应的xml文件,根节点是Map,其实内部就是将数据保存到Map集合中,然后将该集合中的数据写到xml文件中进行保存。
```xml
<map>
Expand All @@ -38,65 +39,49 @@ day02Android数据存储
//注意:调用 commit 提交 数据到文件.
editor.commit();
//editor.clear();

```
3. SQLite

1.创建数据库
1. 创建一个数据库打开的帮助类继承SQLiteOpenHelper
2. 在构造方法中设置数据库文件的名称、游标工厂为null、数据库的版本 1
3. 重写onCreate()方法,进行数据库表结构的初始化,数据库第一次被创建的时候会调用的方法
4. helper.getReadabledatabase()或者调用helper.getWriteabledatabase()获取数据库的示例只有在调用这两个方法的时候如果数据库不存在才会去创建该数据库。
**注意:SQLite数据库中列一旦创建不能修改,如果一定要修改,需要重新创建表,拷贝数据**
```java
4. SQLiteDatabase
Store structured data in a private database.
Android平台中嵌入了一个关系型数据库SQLite,和其他数据库不同的是SQLite存储数据时不区分类型,例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数。除非是主键被定义为Integer,这时只能存储64位整数创建数据库的表时可以不指定数据类型,例如:
`CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))`
`CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name)`
SQLite支持大部分标准SQL语句,增删改查语句都是通用的,分页查询语句和MySQL相同
`SELECT * FROM person LIMIT 20 OFFSET 10`
`SELECT * FROM person LIMIT 10,20`
1. 继承SQLiteOpenHelper
```java
public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {

private static final String TAG = "NoteSQLiteOpenHelper";
/**
* context 上下文 name 数据库的名称 cursorfactory 游标工厂 一般设置null 默认游标工厂 version 数据库的版本
* 版本号从1开始的
*
* @param context
*/
public NoteSQLiteOpenHelper(Context context) {
super(context, "note.db", null, 3);
super(context, "note.db", null, 1);
}

/**
* oncreate 方法 会在数据库第一创建的时候的是被调用 适合做数据库表结构的初始化
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "oncreate 方法被调用了...");
db.execSQL("create table account (id integer primary key autoincrement , name varchar(20), money varchar(20) )");
}

@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
Log.i(TAG,"onupdate 方法被调用了 ,在这个方法里面做更新数据库表结构的操作");
db.execSQL("DROP TABLE IF EXISTS " + "account");
db.execSQL("DROP TABLE IF EXISTS " + account);
this.onCreate(db);
}
}
```

2. 增删改查的第一种方式
1.
insert into account (name,money) values ('买饭','18')
2.
select * from account
3.
update account set money ='19' where id='1'
4.
delete from account where id='1'
5. 分页查询
SELECT * FROM person LIMIT 20 OFFSET 10
SELECT * FROM person LIMIT 10,20

```java
/**
* 记账本的dao
*
* @author Administrator
*
*/
2. 获取
```java
public class NoteDao {
// 因为 任何一个操作都是需要 得到 NoteSQLiteOpenHelper helper
// 把他放在构造方法里面初始化
Expand Down Expand Up @@ -184,8 +169,7 @@ day02Android数据存储
}
```

3. 增删改查第二种方式
```java
```java
public class NoteDao2 {
private NoteSQLiteOpenHelper helper;

Expand Down Expand Up @@ -267,27 +251,17 @@ day02Android数据存储
}
}
```

4. getReadableDatabase()与getWritableDatabase()的区别
4. getReadableDatabase()与getWritableDatabase()的区别
通过观察源码我们发现getWritableDatabase()与getReadableDatabase()内部都是调用了getDatabaseLocked(boolean writeable),只不过是传递的参数不同。getReadableDatabase()会判断当前是否有已经打开的数据库,如果有就直接返回当前的数据库,如果没有的话就去打开数据库,而getWritableDatabase()会去判断当前的数据库是否只是可读的,如果只是可读的数据库,就会去重新打开一个可写的数据库然后返回。其实他俩的区别就在用同步的问题。因为写数据库是要加锁的,而读数据库并不需要锁.
5. Sqlite3工具
有些手机无法进入data/data/package目录下导出数据库,这时候可以adb shell进来后进入到数据库的文件夹。然后执行 sqlite 3 note.db,之后就可以去执行相应的sql语句进行查询相应的数据。
4. ContentProvider
有些程序的数据是私有的不允许别的应用程序访问,例如系统的联系人,但是有些其他的应用程序还想取访问另一个程序的应用数据。这时候就需要一个中间人。这个中间人就是内容提供者。首先这个应用程序需要自己想去暴露内容给这个内容提供者,这样内容提供者才能够得到这些数据。
1. 写一个类继承ContentProvider
2. 在清单文件中配置这个内容提供者,并且配置android:authorities
```xml
<provider
android:name="com.itheima.note.provider.NoteInfoProvider"
android:authorities="com.itheima.note.noteprovider" >
</provider>

```
5. Network
5. Network
Store data on the web with your own network server.

2. 清除缓存&清除数据
清除数据会清除/data/data/包名中的所有文件
getCacheDir() /data/data/<当前应用程序包名>/cache/,清除缓存的时候会清除该目录中的内容---
getCacheDir() /data/data/<当前应用程序包名>/cache/,清除缓存的时候会清除该目录中的内容
---

- 邮箱 :charon.chui@gmail.com
- Good Luck!
- Good Luck!
152 changes: 152 additions & 0 deletions day03内容提供者.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
day02Android数据存储
===

1. ContentProvider
一个可以在不同应用程序间共享数据的组件,相当于一个中间人,一边把数据暴露给这个中间人,另一边是别的应用通过这个中间人获取相应的数据。
1. 继承ContentProvider,并实现相应的方法,由于是一个中间人,我们要检查这个中间人是不是冒牌的,所以就要去验证URI
```java
public class NoteInfoProvider extends ContentProvider {

private static final int QUERY = 1;
private static final int INSERT = 2;
private static final int DELETE = 3;
private static final int UPDATE = 4;

// 参数code 代表如果uri不匹配的返回值
// 在当前应用程序的内部 声明一个路径的检查者
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private SQLiteDatabase db;

static {
// 建立一个匹配规则
// 1.如果发现一个路径 com.itheima.note.noteprovider/query 查询的操作
matcher.addURI("com.itheima.note.noteprovider", "query", QUERY);
matcher.addURI("com.itheima.note.noteprovider", "insert", INSERT);
matcher.addURI("com.itheima.note.noteprovider", "delete", DELETE);
matcher.addURI("com.itheima.note.noteprovider", "update", UPDATE);
}

@Override
public boolean onCreate() {
NoteSQLiteOpenHelper helper = new NoteSQLiteOpenHelper(getContext());
db = helper.getWritableDatabase();
return false;
}

/**
* 内容提供者暴露的查询的方法.
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 1.重要的事情 ,检查 uri的路径.
int code = matcher.match(uri);
if (code == QUERY) {
// 查询处理
NoteSQLiteOpenHelper helper = new NoteSQLiteOpenHelper(getContext());
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from account", null);
return cursor;
} else {
throw new IllegalArgumentException("路径不能被识别,我不认识你...");
}
}

@Override
public String getType(Uri uri) {
int code = matcher.match(uri);
if (code == QUERY) {
//返回一条数据
return "vnd.android.cursor.item/note";
//返回多条数据
//return "vnd.android.cursor.dir/note"
}
return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
int code = matcher.match(uri);
if (code == INSERT) {
db.insert("account", null, values);
} else {
throw new IllegalArgumentException("路径不能被识别,我不认识你...");
}

return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = matcher.match(uri);
if (code == DELETE) {
db.delete("account", selection, selectionArgs);
} else {
throw new IllegalArgumentException("路径不能被识别,我不认识你...");
}

return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = matcher.match(uri);
if (code == UPDATE) {
db.update("account", values, selection, selectionArgs);
} else {
throw new IllegalArgumentException("路径不能被识别,我不认识你...");
}
return 0;
}
}
```
2. 在清单文件中进行注册,并且指定其authorities
```xml
<provider
android:name="com.itheima.note.provider.NoteInfoProvider"
android:authorities="com.itheima.note.noteprovider" >
```
3. 在另外一个应用程序中使用内容提供者获取数据,使用ContentResolver去操作ContentProvider,ContentResolver用于管理ContentProvider实例,并且可实现找到指定的Contentprovider并获取到Contentprovider的数据。
```java
public void query(View view){
//得到内容提供者的解析器 中间人
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.itheima.note.noteprovider/queryaa");
Cursor cursor = resolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
int id = cursor.getInt(cursor.getColumnIndex("id"));
float money = cursor.getFloat(cursor.getColumnIndex("money"));
System.out.println("id="+id+",name="+name+",money="+money);
}
cursor.close();
}
public void insert(View view){
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.itheima.note.noteprovider/insert");
ContentValues values = new ContentValues();
values.put("name", "买洗头膏");
values.put("money", 22.58f);
resolver.insert(uri, values);
}
public void update(View view){
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.itheima.note.noteprovider/update");
ContentValues values = new ContentValues();
values.put("name", "买洗头膏");
values.put("money", 42.58f);
resolver.update(uri, values, "name=?", new String[]{"买洗头膏"});
}
public void delete(View view){
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.itheima.note.noteprovider/delete");
resolver.delete(uri, "name=?", new String[]{"买洗头膏"});
}
```
---

- 邮箱 :[email protected]
- Good Luck!
60 changes: 60 additions & 0 deletions 死锁.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
死锁
===

```java
/**
* 死锁的原因就是同步的嵌套
*/
public class DeadLockTest {
public static void main(String[] args) {
Thread t1 = new Thread(new PrintRunnable(true));
Thread t2 = new Thread(new PrintRunnable(false));
t1.start();
t2.start();
}
}

class MyLock {
static Object locka = new Object();
static Object lockb = new Object();
}

class PrintRunnable implements Runnable {
private boolean flag;

PrintRunnable(boolean flag) {
this.flag = flag;
}

public void run() {
if (flag) {
while (true) {
synchronized (MyLock.locka) {
System.out.println(Thread.currentThread().getName()
+ "...if locka ");
synchronized (MyLock.lockb) {
System.out.println(Thread.currentThread().getName()
+ "..if lockb");
}
}
}
} else {
while (true) {
synchronized (MyLock.lockb) {
System.out.println(Thread.currentThread().getName()
+ "..else lockb");
synchronized (MyLock.locka) {
System.out.println(Thread.currentThread().getName()
+ ".....else locka");
}
}
}
}
}
}
```

---

- 邮箱 :[email protected]
- Good Luck!
Loading

0 comments on commit 28fe0f7

Please sign in to comment.