android 基礎知識三

Android Inflate()方法用途
Android Inflate()方法的作用是將xml定義的一個佈局找出來,但僅僅是找出來而且隱藏的,沒有找到的同時並顯示功能。最近做的一個項目就是這一點讓我迷茫了好幾天。
Android上還有一個與Inflate()功能類似的方法叫findViewById(),二者有時可以互換使用,但也有區別:
如果你的Activity裏用到別的layout,比如對話框layout,你還要設置這個layout上的其他組件的內容,你就必須用inflate()方法先將對話框的layout找出來,然後再用findViewById()找到它上面的其它組件。例如:

  1. View view1=View.inflate(this,R.layout.dialog_layout,null);
  2. TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
  3. dialogTV.setText("abcd");
複製代碼
注:R.id.dialog_tv是在對話框layout上的組件,而這時若直接用this.findViewById(R.id.dialog_tv)就會報錯。

  1. View viewStub = ((ViewStub) findViewById(R.id.stubView)).inflate();
複製代碼
Inflate()可理解爲“隱性膨脹”,隱性擺放在view裏,inflate()前只是獲得控件,但沒有大小沒有在View裏佔據空間,inflate()後有一定大小,只是處於隱藏狀態。

Android NotesList詳解
我們從入口點所在的activity開始,可以看到這個activity最重要的功能就是顯示日誌記錄。這個程序的日誌都存放在Sqlite數據庫中,因此需要讀出所有的日誌記錄並顯示出來。
先來看兩個重要的私有數據,第一個PROJECTION字段指明瞭“日誌列表“所關注的數據庫中的字段(即只需要ID和Title就可以了)。

  1. private static final String[] PROJECTION =
  2. new String[] {
  3.     Notes._ID, // 0
  4.     Notes.TITLE, // 1
  5. };
複製代碼
第二個字段COLUMN_INDEX_TITLE指明title字段在數據表中的索引。

  1. private static final int COLUMN_INDEX_TITLE =1;
  2. //然後就進入了第一個調用的函數onCreate。   
  3. Intent intent = getIntent();
  4. if (intent.getData() == null)
  5. {
  6.     intent.setData(Notes.CONTENT_URI);
  7. }
複製代碼
因爲NotesList這個activity是系統調用的,此時的intent是不帶數據和操作類型的,系統只是在其中指明瞭目標組件是Notelist,所以這裏把”content:// eoe”保存到intent裏面,這個URI地址指明瞭數據庫中的數據表名,也就是保存日誌的數據表notes。

  1. Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, Notes.DEFAULT_SORT_ORDER);
複製代碼
然後調用managedQuery函數查詢出所有的日誌信息,這裏第一個參數就是上面設置的” content:// ”這個URI,即notes數據表。PROJECTION 字段指明瞭結果中所需要的字段,Notes.DEFAULT_SORT_ORDER 指明瞭結果的排序規則。實際上managedQuery並沒有直接去查詢數據庫,而是通過Content Provider來完成實際的數據庫操作,這樣就實現了邏輯層和數據庫層的分離。

  1. SimpleCursorAdapter adapter =new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
  2. new String[] { Notes.TITLE }, newint[] { android.R.id.text1 });
  3. setListAdapter(adapter);
複製代碼
查詢出日誌列表後,構造一個CursorAdapter,並將其作爲List View的數據源,從而在界面上顯示出日誌列表。可以看到,第二個參數是R.layout.noteslist_item,打開對應的noteslist_item.xml文件,

  1. <TEXTVIEW android:singleLine="true" android:paddingLeft="5dip"
  2. android:gravity="center_vertical"
  3. android:textAppearance="?android:attr/textAppearanceLarge"
  4. android:layout_height="?android:attr/listPreferredItemHeight"
  5. android:layout_width="fill_parent"
  6. android:id="@android:id/text1" xmlns:android="http://schemas.android.com/apk/res/android" />
複製代碼
就是用來顯示一條日誌記錄的TextView,最後兩個字段指明瞭實際的字段映射關係,通過這個TextView來顯示日誌的title字段。
處理“選擇日誌”事件
既然有了“日誌列表”,就自然要考慮如何處理某一條日誌的單擊事件,這通過重載onListItemClick方法來完成,

  1. @Override
  2. protected void onListItemClick(ListView l, View v, int position, long id) {
  3.     Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
  4.       
  5.     String action = getIntent().getAction();
  6.     if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
  7.         setResult(RESULT_OK, new Intent().setData(uri));
  8.     }
  9.     else {
  10.         startActivity(new Intent(Intent.ACTION_EDIT, uri));
  11.     }
  12. }
複製代碼
Android MemoryFile高性能文件類
很多網友抱怨Android處理底層I/O性能不是很理想,如果不想使用NDK則可以通過Android MemoryFile類實現高性能的文件讀寫操作。 MemoryFile顧名思義就是內存文件的意思,如果你過去從事過Win32開發,那麼它的原理就是MapViewOfFile(),開發過Linux的網友可能很快就聯想到了mmap(),是的該類就是他們的託管代碼層封裝,位於android.os.MemoryFile這個位置,從Android 1.0開始就被支持。

MemoryFile適用於哪些地方呢?

對於I/O需要頻繁操作的,主要是和外部存儲相關的I/O操作,MemoryFile通過將NAND或SD卡上的文件,分段映射到內存中進行修改處理,這樣就用高速的RAM代替了ROM或SD卡,性能自然提高不少,對於Android手機而言同時還減少了電量消耗。該類實現的功能不是很多,直接從Object上繼承,通過JNI的方式直接在C底層執行。

主要的構造方法MemoryFile(String name, int length),這裏第二個參數爲文件大小,需要說明的是Android的MemoryFile和傳統的mmap還有一點點區別,畢竟是手機,它內部的內存管理方式ashmem會從內核中回收資源。

synchronized boolean allowPurging(boolean allowPurging)  //允許ashmem清理內存,線程安全同步的方式。
void close() //關閉,因爲在Linux內部mmap佔用一個句柄,不用時一定要釋放了
InputStream  getInputStream()  返回讀取的內容用Java層的InputStream保存
OutputStream  getOutputStream()  把一個OutputSream寫入到MemoryFile中
boolean  isPurgingAllowed() //判斷是否允許清理
int length()  //返回內存映射文件大小


下面就是我們熟悉的讀寫細節,主要是對字符數組的操作,這裏大家要計算好每個文件類型的佔用,同時考慮到效率對於自己分配的大小考慮粒度對齊。
  1. [/size][/font]
  2. int readBytes(byte[] buffer, int srcOffset, int destOffset, int count)
  3. void writeBytes(byte[] buffer, int srcOffset, int destOffset, int count)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章