Android Inflate()方法的作用是將xml定義的一個佈局找出來,但僅僅是找出來而且隱藏的,沒有找到的同時並顯示功能。最近做的一個項目就是這一點讓我迷茫了好幾天。
Android上還有一個與Inflate()功能類似的方法叫findViewById(),二者有時可以互換使用,但也有區別:
如果你的Activity裏用到別的layout,比如對話框layout,你還要設置這個layout上的其他組件的內容,你就必須用inflate()方法先將對話框的layout找出來,然後再用findViewById()找到它上面的其它組件。例如:
- View view1=View.inflate(this,R.layout.dialog_layout,null);
- TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
- dialogTV.setText("abcd");
- View viewStub = ((ViewStub) findViewById(R.id.stubView)).inflate();
Android NotesList詳解
我們從入口點所在的activity開始,可以看到這個activity最重要的功能就是顯示日誌記錄。這個程序的日誌都存放在Sqlite數據庫中,因此需要讀出所有的日誌記錄並顯示出來。
先來看兩個重要的私有數據,第一個PROJECTION字段指明瞭“日誌列表“所關注的數據庫中的字段(即只需要ID和Title就可以了)。
- private static final String[] PROJECTION =
- new String[] {
- Notes._ID, // 0
- Notes.TITLE, // 1
- };
- private static final int COLUMN_INDEX_TITLE =1;
- //然後就進入了第一個調用的函數onCreate。
- Intent intent = getIntent();
- if (intent.getData() == null)
- {
- intent.setData(Notes.CONTENT_URI);
- }
- Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, Notes.DEFAULT_SORT_ORDER);
- SimpleCursorAdapter adapter =new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
- new String[] { Notes.TITLE }, newint[] { android.R.id.text1 });
- setListAdapter(adapter);
- <TEXTVIEW android:singleLine="true" android:paddingLeft="5dip"
- android:gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_width="fill_parent"
- android:id="@android:id/text1" xmlns:android="http://schemas.android.com/apk/res/android" />
處理“選擇日誌”事件
既然有了“日誌列表”,就自然要考慮如何處理某一條日誌的單擊事件,這通過重載onListItemClick方法來完成,
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
-
- String action = getIntent().getAction();
- if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
- setResult(RESULT_OK, new Intent().setData(uri));
- }
- else {
- startActivity(new Intent(Intent.ACTION_EDIT, uri));
- }
- }
很多網友抱怨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() //返回內存映射文件大小
下面就是我們熟悉的讀寫細節,主要是對字符數組的操作,這裏大家要計算好每個文件類型的佔用,同時考慮到效率對於自己分配的大小考慮粒度對齊。
- [/size][/font]
- int readBytes(byte[] buffer, int srcOffset, int destOffset, int count)
- void writeBytes(byte[] buffer, int srcOffset, int destOffset, int count)