android 基础知识三

时间:2022-02-17 19:11:57
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)