Android零碎知识



一、android:stopWithTask 用于 <service> 可在 R.attr 中找到,有两个疑惑:

        1、为啥在R.attr中找到?它里面不都是Resource的ID吗.

        2、不知道这个标签对 service 有什么影响

二、LinearLayout 有一个 android:gravity 属性用于设置其内部 view 摆放方式,如 垂直居中、水平居中等

三、

TextUtils.isEmpty(mSearchString)

检查一个字符串是否为空,注意 TextUtils 工具类的使用



四、Java Exception 是不跨线程的, 有时间仔细研究下


五、 ContentUris 工具类有时间仔细看下文档/ Uri 有时间仔细看下文档/ UriBiulder/

六、View --> TextView --> EditView 这个文档要看

七、



​[java] 

view plain

copy

  1. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  2. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, mySortOrder);
  3. //Cursor ContentResolver Uri 之间的关系是什么
  4. c.setNotificationUri(getContext().getContentResolver(), uri);
  5. return c;

​[java]​ 

view plain

copy

  1. long rowId = db.insert(NOTES_TABLE_NAME, null, contentValues);
  2. if(rowId > 0) {
  3. Uri newUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
  4. //这里的 ContentResolver.notifyChange(Uri,null)做了什么工作?
  5. //和 Cursor.setNotificationUri()有什么关系
  6. getContext().getContentResolver().notifyChange(newUri, null);
  7. return newUri;
  8. } else {
  9. // android.database.SQLException
  10. throw new SQLException("Failed to insert row into " + uri);
  11. }

在实现 ContentProvider 的query 时,一般都有下面几行代码:

​[java]​ 

view plain

copy

  1. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  2. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, mySortOrder);
  3. //这一行的代码的作用?
  4. c.setNotificationUri(getContext().getContentResolver(), uri);
  5. return c;

下面具体说下注释的那行的作用?

从字面上看 setNotificationUri, 即 Uri 有改变时对本 Cursor 发出通知.

查看 AbstractCursor.setNotificationUri 源代码如下:

​[java]​ 

view plain

copy

  1. public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
  2. mContentResolver = cr;
  3. mNotifyUri = notifyUri;
  4. mSelfObserver = new SelfContentObserver(this);
  5. //cr.registerContentObserver(notifyUri, mSelfObserver)
  6. mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
  7. }

这个方法的作用就是在 ContentResolver上注册一个 Observer,

当 ContentResolver.notifyChange 时将调用已经注册的 ContentObserver, 你可以通过调用 ContentResolver.registerContentObserver 明确的给 ContentReselover注册观察者,

在这里我们并没有明确的调用 registerContentReselover方法, 而是通过 Cursor.setNotificationUri 间接的注册了一个 ContentObserver.

这个间接注册的好处是什么呢?

间接注册时的 ContentObserver 是 AbstractCursor的一个内部类, 这个以内部类形式存在的 ContentObserver把 AbstractCursor关联进去.

总体上的过程为:

​[java]​ 

view plain

copy

  1. //这个 Cursor 会被 Context.getContentResolver().query() 返回
  2. Cursor c = SQLiteDatabase.query();
  3. // 在 ContentResolver上注册一个 ContentObserver
  4. c.setNotificationUri(ContentResolver,Uri)
  5. //如果ContentObserver参数为null, 则ContentResolver会通知上一步注册的ContentObserver
  6. getContentResolver().notifyChange(Uri,ContentObserver)
  7. //Abstract Cursor 源码中的 setNotificationUri方法下的
  8. new SelfContentObserver(this) //会获得ContentResolver发出的通知

SelfContentObserver会通知和其关联的Cursor(初始化SelfContentObserver时进行关联)

Cursor会调用 onChange 通知自己的 ContentObserver. 其中默认的 ContentObserver是 CursorAdapter

也就是说 Cursor 也有 ContentObserver, 而它的默认 ContentObserver是在这个时候设立的:

​[java]​ 

view plain

copy

  1. //在这个构造数内会设置 Cursor 的观察者为 CursorAdapter,具体可以查看源代码跟踪一下
  2. SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.notes_list_item,
  3. c/* 指Cursor */, new String[]{NotePad.Notes.TITLE}, new int[]{R.id.text1});

另外Uri参数的用处没有搞太清楚,但总体上是:

content://com.example.notepad/notes/5 这种Uri也会引起 content://com.example.notepad/notes 这种Uri的改变

八、Menu下面的一个方法:

​[java]​ 

view plain

copy

  1. int addIntentOptions(int groupId, int itemId, int order, ComponentName caller, Intent[] specifics,Intent intent, int flags, MenuItem[] outSpecificItems);

这个方法中的第六个参数 intent, 一般Action为null, 并且设置Data为当前Activity相关的,同时包含Category为CATEGORY_ALTERNATIVE或CATEGORY_SECOND_ALTERNATIVE. (如果一个Activity的<intent-filter>声明为CATEGORY_ALTERNATIVE则这个Activity可以在另一个Activity的Options Menu中出现)

解释这个方法的几个参数含义:

groupId: 如果有多外intent-filter满足 intent,则会出现多个 MenuItem,这些MenuItem都属于这个 groupId

itemId: 

order:

ComponentName: 此菜单属于的那个 Activity

specifics: 如果有多外intent-filter满足intent, 则specifics指定了它们的顺序

flags: 

outSpecificItems: 对应 specifics的menuItem

九、public boolean onOptionsItemSelected(MenuItem item)

这个方法的返回值应该特别的注意, 如果返回true, 则系统不会再处理后续事情. 在一些情况下是不能返回 ture的, 如你在 onCreateOptionsMenu 方法中调用 Menu.addIntentOptions 方法生成菜单项, 当这个菜单项被点击时后续的处理应该由系统完成,如果你返回 true,那么系统就不再处理后续流程.

十、

TextView 属性:

android:ems 指TextView的宽可以容纳25个英文字符

android:autoText 使此TextView可以纠错

十一、

可以在 layout.xml 文件中这样使用你自己定义的组件

​[html]​ 

view plain

copy

  1. <view xmlns:android="http://schemas.android.com/apk/res/android"
  2. class="com.example.android.notepad.NoteEditor$LinedEditText"
  3. android:id="@+id/note"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:background="@android:color/transparent"
  7. android:padding="5dip"
  8. android:scrollbars="vertical"
  9. android:fadingEdge="vertical"
  10. android:gravity="top"
  11. android:textSize="22sp"
  12. android:capitalize="sentences"
  13. />

当然也可以这样使用:

​[html]​ 

view plain

copy

  1. <com.example.android.notepad.NoteEditor$LinedEditText xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/note"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@android:color/transparent"
  6. android:padding="5dip"
  7. android:scrollbars="vertical"
  8. android:fadingEdge="vertical"
  9. android:gravity="top"
  10. android:textSize="22sp"
  11. android:capitalize="sentences"
  12. />

一、android:stopWithTask 用于 <service> 可在 R.attr 中找到,有两个疑惑:

        1、为啥在R.attr中找到?它里面不都是Resource的ID吗.

        2、不知道这个标签对 service 有什么影响

二、LinearLayout 有一个 android:gravity 属性用于设置其内部 view 摆放方式,如 垂直居中、水平居中等

三、

TextUtils.isEmpty(mSearchString)

检查一个字符串是否为空,注意 TextUtils 工具类的使用

四、Java Exception 是不跨线程的, 有时间仔细研究下

五、 ContentUris 工具类有时间仔细看下文档/ Uri 有时间仔细看下文档/ UriBiulder/

六、View --> TextView --> EditView 这个文档要看

七、

​[java]​  view plain​ ​copy

  1. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  2. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, mySortOrder);
  3. //Cursor ContentResolver Uri 之间的关系是什么
  4. c.setNotificationUri(getContext().getContentResolver(), uri);
  5. return c;

​[java]​  view plain​ ​copy

  1. long rowId = db.insert(NOTES_TABLE_NAME, null, contentValues);
  2. if(rowId > 0) {
  3. Uri newUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
  4. //这里的 ContentResolver.notifyChange(Uri,null)做了什么工作?
  5. //和 Cursor.setNotificationUri()有什么关系
  6. getContext().getContentResolver().notifyChange(newUri, null);
  7. return newUri;
  8. } else {
  9. // android.database.SQLException
  10. throw new SQLException("Failed to insert row into " + uri);
  11. }

在实现 ContentProvider 的query 时,一般都有下面几行代码:

​[java]​  view plain​ ​copy

  1. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  2. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, mySortOrder);
  3. //这一行的代码的作用?
  4. c.setNotificationUri(getContext().getContentResolver(), uri);
  5. return c;

下面具体说下注释的那行的作用?

从字面上看 setNotificationUri, 即 Uri 有改变时对本 Cursor 发出通知.

查看 AbstractCursor.setNotificationUri 源代码如下:

​[java]​  view plain​ ​copy

  1. public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
  2. mContentResolver = cr;
  3. mNotifyUri = notifyUri;
  4. mSelfObserver = new SelfContentObserver(this);
  5. //cr.registerContentObserver(notifyUri, mSelfObserver)
  6. mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
  7. }

这个方法的作用就是在 ContentResolver上注册一个 Observer,

当 ContentResolver.notifyChange 时将调用已经注册的 ContentObserver, 你可以通过调用 ContentResolver.registerContentObserver 明确的给 ContentReselover注册观察者,

在这里我们并没有明确的调用 registerContentReselover方法, 而是通过 Cursor.setNotificationUri 间接的注册了一个 ContentObserver.

这个间接注册的好处是什么呢?

间接注册时的 ContentObserver 是 AbstractCursor的一个内部类, 这个以内部类形式存在的 ContentObserver把 AbstractCursor关联进去.

总体上的过程为:

​[java]​  view plain​ ​copy

  1. //这个 Cursor 会被 Context.getContentResolver().query() 返回
  2. Cursor c = SQLiteDatabase.query();
  3. // 在 ContentResolver上注册一个 ContentObserver
  4. c.setNotificationUri(ContentResolver,Uri)
  5. //如果ContentObserver参数为null, 则ContentResolver会通知上一步注册的ContentObserver
  6. getContentResolver().notifyChange(Uri,ContentObserver)
  7. //Abstract Cursor 源码中的 setNotificationUri方法下的
  8. new SelfContentObserver(this) //会获得ContentResolver发出的通知

SelfContentObserver会通知和其关联的Cursor(初始化SelfContentObserver时进行关联)

Cursor会调用 onChange 通知自己的 ContentObserver. 其中默认的 ContentObserver是 CursorAdapter

也就是说 Cursor 也有 ContentObserver, 而它的默认 ContentObserver是在这个时候设立的:

​[java]​  view plain​ ​copy

  1. //在这个构造数内会设置 Cursor 的观察者为 CursorAdapter,具体可以查看源代码跟踪一下
  2. SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.notes_list_item,
  3. c/* 指Cursor */, new String[]{NotePad.Notes.TITLE}, new int[]{R.id.text1});

另外Uri参数的用处没有搞太清楚,但总体上是:

content://com.example.notepad/notes/5 这种Uri也会引起 content://com.example.notepad/notes 这种Uri的改变

八、Menu下面的一个方法:

​[java]​  view plain​ ​copy

  1. int addIntentOptions(int groupId, int itemId, int order, ComponentName caller, Intent[] specifics,Intent intent, int flags, MenuItem[] outSpecificItems);

这个方法中的第六个参数 intent, 一般Action为null, 并且设置Data为当前Activity相关的,同时包含Category为CATEGORY_ALTERNATIVE或CATEGORY_SECOND_ALTERNATIVE. (如果一个Activity的<intent-filter>声明为CATEGORY_ALTERNATIVE则这个Activity可以在另一个Activity的Options Menu中出现)

解释这个方法的几个参数含义:

groupId: 如果有多外intent-filter满足 intent,则会出现多个 MenuItem,这些MenuItem都属于这个 groupId

itemId: 

order:

ComponentName: 此菜单属于的那个 Activity

specifics: 如果有多外intent-filter满足intent, 则specifics指定了它们的顺序

flags: 

outSpecificItems: 对应 specifics的menuItem

九、public boolean onOptionsItemSelected(MenuItem item)

这个方法的返回值应该特别的注意, 如果返回true, 则系统不会再处理后续事情. 在一些情况下是不能返回 ture的, 如你在 onCreateOptionsMenu 方法中调用 Menu.addIntentOptions 方法生成菜单项, 当这个菜单项被点击时后续的处理应该由系统完成,如果你返回 true,那么系统就不再处理后续流程.

十、

TextView 属性:

android:ems 指TextView的宽可以容纳25个英文字符

android:autoText 使此TextView可以纠错

十一、

可以在 layout.xml 文件中这样使用你自己定义的组件

​[html]​  view plain​ ​copy

  1. <view xmlns:android="http://schemas.android.com/apk/res/android"
  2. class="com.example.android.notepad.NoteEditor$LinedEditText"
  3. android:id="@+id/note"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:background="@android:color/transparent"
  7. android:padding="5dip"
  8. android:scrollbars="vertical"
  9. android:fadingEdge="vertical"
  10. android:gravity="top"
  11. android:textSize="22sp"
  12. android:capitalize="sentences"
  13. />

当然也可以这样使用:

​[html]​  view plain​ ​copy

  1. <com.example.android.notepad.NoteEditor$LinedEditText xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/note"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@android:color/transparent"
  6. android:padding="5dip"
  7. android:scrollbars="vertical"
  8. android:fadingEdge="vertical"
  9. android:gravity="top"
  10. android:textSize="22sp"
  11. android:capitalize="sentences"
  12. />