消息机制这个玩意儿,理解起来还是有点费劲的。要理解清楚的话需要对线程有很好的理解,出此之外还要掌握好消息机制的用法。这里我用的是Android里的一个工具类叫AsyncTask,这个类使用泛型指定了3个参数。第一个参数是启动任务需要的参数类型,第二个参数表示后台执行任务的百分比,第三个参数表示任务完成之后返回的信息。下面就一步一步的做这个小例子。
1.主界面准备一个ListView来显示文件信息,辅助界面是信息的主体如下所示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
下面是辅助界面
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TableRow>
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</TableRow>
</TableLayout>
2.下面先来这个比较复杂的类,这个类继承AsyncTask
private class ListFileTools extends AsyncTask<File, File, String>{
@Override
protected void onProgressUpdate(File... values) {
Map<String,Object> fileItem=new HashMap<String, Object>();
//如果为目录
if(values[0].isDirectory()){
fileItem.put("img", R.drawable.folder_close);
}else{
fileItem.put("img", R.drawable.file);
}
fileItem.put("name", values[0]);
ListActivity.this.allFileItems.add(fileItem);
//包装数据
ListActivity.this.simple=new SimpleAdapter(ListActivity.this,
allFileItems, R.layout.file_list, new String[]{"img","name"}, new int[]{R.id.img,R.id.name});
ListActivity.this.fileList.setAdapter(ListActivity.this.simple);
}
@Override
protected String doInBackground(File... params) {
if(!params[0].getPath().equals(java.io.File.separator)){
Map<String,Object> fileItem=new HashMap<String, Object>();
fileItem.put("img", R.drawable.folder_open);
fileItem.put("name", params[0].getParentFile());
ListActivity.this.allFileItems.add(fileItem);
}
if(params[0].isDirectory()){
File tempFile[]=params[0].listFiles();
if(tempFile!=null){
for(int i=0;i<tempFile.length;i++){
this.publishProgress(tempFile[i]);
}
}
}
return "文件已经列出";
}
}
这里代码不是很复杂关键在于理解,我们执行后台任务的时候传递的是文件对象,更新主界面UI返回的是File类型,返回的信息则是string类型。
3.activity载入的时候我们需要执行后台任务,列出一级文件夹和文件,listview被点击时也执行这个任务列出子文件夹的信息
private List<Map<String,Object>> allFileItems=new ArrayList<Map<String,Object>>();
private SimpleAdapter simple=null;
private ListView fileList=null;
private ListFileTools tools=null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.fileList=(ListView)super.findViewById(R.id.list);
//从根目录列出所有文件
File filePath=new File(java.io.File.separator);
//定义子任务
tools=new ListFileTools();
tools.execute(filePath);
this.fileList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
File currentFile=(File)ListActivity.this.allFileItems.get(position).get("name");
if(currentFile.isDirectory()){
ListActivity.this.allFileItems=new ArrayList<Map<String,Object>>();
ListFileTools tool=new ListFileTools();
tool.execute(currentFile);
}
}
});
}
代码看起来有点多,但是这的确是个很好的例子,下面来看看效果图