Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1015575
  • 博文数量: 123
  • 博客积分: 5051
  • 博客等级: 大校
  • 技术积分: 1356
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-14 10:56
文章分类
文章存档

2012年(1)

2011年(21)

2010年(13)

2009年(55)

2008年(33)

分类: Java

2008-12-07 13:26:08

应用程序:Home Contacts Phone Browser ...
应用框架:Activity Manager  、Window Manager 、Content Providers、View System、Packager Manager、Telephony Manager、Resource Manager、Location Manager、Notification Manager.
Linux内核:Display Driver、Camera Driver、Flash Memory Driver、Binder Driver、Keypad Driver、WiFi Driver、Audio Drivers、Power Mangement.

下面所有的应用是andriod中的整套服务体系和相关系统,包括:
Views 能被用来编译一个应用程序,包括lists,grids,text boxes,buttons和可以嵌套的网页
Content Providers使应用程序能够从其他的应用程序中接收数据,例如Contacts,或者是分享它们自己的数据
资源管理:Resource Manager,提供非代码资源,例如定位strings,graphics,和layout files.
Notification Manager:使所有的应用程序陈列出alerts,这是在状态栏中实现的。
Activity Manager:管理应用程序的生命周期并且提供一个常见的导航归栈

类库
系统C类库,为的是设备嵌入式开发
媒体类库:基于PacketVideo's OpenCORE,这个类库支持回放和多种音频和视频格式的录音,以及静态图像文件,包括MPEG4,H.264,MP3,AAC,AMR,JPG和PNG
界面管理:2D和3D
LibWebCore一个现代的网页浏览器
SGL:2D图像启动器
FreeType和SQLite
每一个Android应用都在他自己的进程中运行,

如果想让你的数据是共有的,那么你 需要创建一个内容提供者,这个对象能够被所有的应用程序存储和返回可被获得
的数据。在包中这是唯一的分享数据的方法。

Android提供了下面机制用来存储和获取数据:Preferences、Files、Databases、Content Providers、Network.
Preferences:一个轻量级机制,存储和获得原始数据类型的关键词。这是典型的用来存储数据的首选项。
Files:你能存放你的文件到设备上或者是一个可以移动的存储媒介中。
Databases:这个Android APIS包含SQLite支持,你的应用程序可以创建和使用私有的SQLite 数据.每一个数据都是私有的。
Content Providers:主要用来实现数据公有这一功能。
Network:不要忘记你也同样可以使用network去存储和取回数据.

下面一一介绍Preferences的使用
Preferences:一个轻量级机制,存储和获得原始数据类型的关键词。这是典型的用来存储数据的首选项。
你能享受存储应用程序优先级,就像一个默认的招呼或者是无论何时开始运行应用程序时的文本字体。调用Context.getSharePreferences()读和写数据值。为你所设置的首先项分配一个名称,如果你想将它们分享给同一个包中的其他组件的话,或者是使用Activity.getPreferences()去使它们作为私有使用,这时此函数不需要任何参数。
下面是一个例子:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
     ...      

    @Override
    protected void onCreate(Bundle state){         
       super.onCreate(state);
    
    ...
   
       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
/*
 public abstract SharedPreferences  getSharedPreferences(String name, int mode)
Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.
Parameters
name     Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
mode     Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
Returns

    * Returns the single SharedPreferences instance that can be used to retrieve and modify the preference values.


*/
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }
   
    @Override
    protected void onStop(){
       super.onStop();
   
      // Save user preferences. We need an Editor object to
      // make changes. All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Don't forget to commit your edits!!!
      editor.commit();
    }
}


使用文件Files
Android为本地应用程序提供了读和写流,调用函数Context.openFileOutput()和Context.openFileInput()
去读和写文件,这需要参数:本地名称和路径。你仅仅能获得当前文件,而不能获得另外一个应用程序的文件。
如果你在编译期间有静态文件存在于你所运行的应用程序包中,你可以保存你的文件到你的当前工程中的res/raw/
中,之后使用Resources.openRawResource(R.raw.mydatafile)来实现。
来看看函数Context.openFileOutput()和函数Context.openFileInput():
Context.openFileOutput()
打开一个用来执行写操作的的私有文件,这个私有文件是与当前上下文应用程序包相互关联的。如果文件不存在,那么
就会创建一个。
参数解释:
name     打开文件的名称,但是不能包含路径分隔符The name of the file to open; can not contain path separators.
mode     操作模式,使用值0或是MODE_PRIVATE作为默认应用操作。MODE_APPEND即向一个存在的文件追加内容,
MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE用来控制权限。Operating mode. Use 0 or MODE_PRIVATE
for the default operation, MODE_APPEND to append to an existing file, MODE_WORLD_READABLE
and MODE_WORLD_WRITEABLE to control permissions.
返回值:
    *产生输出流的 FileOutputStream。


Context.openFileInput()
函数原型:
 public abstract FileInputStream  openFileInput(String name)
打开一个用来进行读操作的私有文件,这个文件与当前上下文的应用程序包相关连。
Open a private file associated with this Context's application package for reading.
参数:
name     打开文件的名称,但是不能包含路径分隔符
Returns
 * 产生输入流的FileInputStream。


前面所说的知识都不能在应用程序之间进行共享,现在来说说如何在不同的应用之间进行数据的共享。
Content Providers实现上面所说的共享问题,在Android中,这是唯一一个用来进行数据共享的方法。
下面来具体介绍如何使用Context Provider
使用Content Provider
(一)数据查询
1、每一个contact provider都是通过提供一个公有的URI,这个URI被一个客户用来在对应content provider
中查询 /增加/更新/删除数据。这个URI有两种格式:一个是返回所有的contact,另外一个返回具体的结果。例如:
content://contacts/people/
content://contacts/people/23
我们现在来看看下面的一段代码:
// Get the base URI for contact with _ID=23.
// This is same as Uri.parse("content://contacts/people/23");
Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);
// Query for this record.
Cursor cur = managedQuery(myPerson, null, null, null);
这段代码返回一个查询结果的光标,
你应该使用Activity.managedQuery()方法去获得一个管理光标。一个处理光标操作所有的具体操作,就像你在运
行一段程序的过程中,暂停了,那么就需要Cursor来保存现场,当再次回来时,就可以继续运行了。还有一个更加方
便的方法就是startManagingCursor(),这使用起来更加地方便。
函数原型:
 public final Cursor  managedQuery(Uri uri, String[] projection, String selection, String[]
 selectionArgs, String sortOrder)
Wrapper around query(android.net.Uri, String[], String, String[], String) that gives the
resulting Cursor to call startManagingCursor(Cursor) so that the activity will manage its
lifecycle for you.
参数:
uri     The URI of the content provider to query.
projection     List of columns to return.
selection     SQL WHERE clause.
selectionArgs     The arguments to selection, if any ?s are pesent
sortOrder     SQL ORDER BY clause.
Returns

    * The Cursor that was returned by query().




(二)更改数据
如果要成批地更新记录,调用函数ContentResolver.update(),参数为要改变的columns和values.
 public final int update(Uri uri, ContentValues values, String where, String[] selectionArgs)
Update row(s) in a content URI. If the content provider supports transactions the update will be atomic.
Parameters
uri     The URI to modify.
values     The new field values. The key is the column name for the field. A null value will remove an existing field value.
where     A filter to apply to rows before deleting, formatted as an SQL WHERE clause (excluding the WHERE itself).
Returns

    * the URL of the newly created row

(三)增加记录
为了增加一个新的记录,需要调用ContentResolver.insert()方法。函数原型为:

(四)删除记录
调用ContentResolver.delete(),参数为指定的URI删除一个单一的记录。
Creating a Content Provider
下面是关于如何创建自己的content provider的方法步骤:
Here is how to create your own content provider to act as a public source for reading and
writing a new data type:

   1. Extend ContentProvider.
   2. Define a public static final Uri named CONTENT_URI. This is the string that represents the full "content://" URI that your content provider handles. You must define a unique string for this value; the best solution is to use the fully-qualified class name of your content provider (lowercase). So, for example:
      public static final Uri CONTENT_URI = Uri.parse( "content://com.google.codelab.rssprovider");
   3. Create your system for storing data. Most content providers store their data using Android's file storage methods or SQLite databases, but you can store your data any way you want, so long as you follow the calling and return value conventions.
   4. Define the column names that you will return to your clients. If you are using an underlying database, these column names are typically identical to the SQL database column names they represent. In any case, you should include an integer column named _id to define a specific record number. If using the SQLite database, this should be type INTEGER PRIMARY KEY AUTOINCREMENT. The AUTOINCREMENT descriptor is optional, but by default, SQLite autoincrements an ID counter field to the next number above the largest existing number in the table. If you delete the last row, the next row added will have the same ID as the deleted row. To avoid this by having SQLite increment to the next largest value whether deleted or not, then assign your ID column the following type: INTEGER PRIMARY KEY AUTOINCREMENT. (Note You should have a unique _id field whether or not you have another field (such as a URL) that is also unique among all records.) Android provides the SQLiteOpenHelper class to help you create and manage versions of your database.
   5. If you are exposing byte data, such as a bitmap file, the field that stores this data should actually be a string field with a content:// URI for that specific file. This is the field that clients will call to retrieve this data. The content provider for that content type (it can be the same content provider or another content provider — for example, if you're storing a photo you would use the media content provider) should implement a field named _data for that record. The _data field lists the exact file path on the device for that file. This field is not intended to be read by the client, but by the ContentResolver. The client will call ContentResolver.openOutputStream() on the user-facing field holding the URI for the item (for example, the column named photo might have a value content://media/images/4453). The ContentResolver will request the _data field for that record, and because it has higher permissions than a client, it should be able to access that file directly and return a read wrapper for that file to the client.
   6. Declare public static Strings that clients can use to specify which columns to return, or to specify field values from the cursor. Carefully document the data type of each field. Remember that file fields, such as audio or bitmap fields, are typically returned as string path values
   7. Return a Cursor object over a recordset in reply to a query. This means implementing the query(), update(), insert(), and delete() methods. As a courtesy, you might want to call ContentResolver.notifyChange() to notify listeners about updated information.
   8. Add a tag to AndroidManifest.xml, and use its authorities attribute to define the authority part of the content type it should handle. For example, if your content type is content://com.example.autos/auto to request a list of all autos, then authorities would be com.example.autos. Set the multiprocess attribute to true if data does not need to be synchronized between multiple running versions of the content provider.
   9. If you are handling a new data type, you must define a new MIME type to return for your implementation of android.ContentProvider.getType(url). This type corresponds to the content:// URI submitted to getType(), which will be one of the content types handled by the provider. The MIME type for each content type has two forms: one for a specific record, and one for multiple records. Use the Uri methods to help determine what is being requested. Here is the general format for each:
          * vnd.android.cursor.item/vnd.yourcompanyname.contenttype for a single row. For example, a request for train record 122 using

            content://com.example.transportationprovider/trains/122

            might return the MIME type vnd.android.cursor.item/vnd.example.rail
          * vnd.android.cursor.dir/vnd.yourcompanyname.contenttype for multiple rows. For example, a request for all train records using

            content://com.example.transportationprovider/trains

            might return the MIME type vnd.android.cursor.dir/vnd.example.rail

For an example of a private content provider implementation, see the NodePadProvider class in the notepad sample application that ships with the SDK.

Here is a recap of the important parts of a content URI:

Elements of a content URI

   1. Standard required prefix. Never modified.
   2. Authority part. For third-party applications, this should be a fully-qualified class to ensure uniqueness. This corresponds to the value in the element's authorities attribute:
   3. The path that the content provider uses to determine what kind of data is being requested. This can be zero or more segments: if the content provider exposes only one type of data (only trains, for example), this can be absent. If it provides several types, including subtypes, this can be several elements long: e.g., "land/bus, land/train, sea/ship, and sea/submarine" to give four possibilities.
   4. A specific record being requested, if any. This is the _id value of a specific record being requested. If all records of a specific type are being requested, omit this and the trailing slash: content://com.example.transportationprovider/trains


android中网路数据操作部分和java中网路操作部分是一样的,即在包java.net.*;中介绍。





 
阅读(5729) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~