- 浏览: 674446 次
- 性别:
- 来自: 安徽
文章分类
- 全部博客 (252)
- Html/Div+CSS (12)
- Js/Jquery (34)
- Flex (2)
- Ajax (3)
- Java (35)
- C# (15)
- Spring (16)
- Hibernate (13)
- Struts2 (12)
- Struts1 (7)
- DWR (1)
- iBatis/myBatis (9)
- Tag(JSTL、EL) (1)
- Android (44)
- SQL (7)
- SEO (7)
- Exception (3)
- Tool (10)
- Other (3)
- WebService (9)
- Apache (7)
- Ext (0)
- Utils (12)
- thinking in programme (2)
- Hadoop (0)
- ActiveMQ (0)
- HTML5/CSS3 (0)
- WPF (1)
- NodeJs (1)
- 设计模式 (0)
- 程序人生 (1)
- 随笔 (1)
- Linux (1)
- Load Balance (0)
最新评论
-
drinkjava2:
太复杂了而且不通用,利用ThreadLocal可完美解决这一问 ...
JDBC的多条件动态查询 -
u013107014:
multipartRequest.getFiles(" ...
多文件上传 by MultipartFile and Multiple -
liyys:
可惜没讲你mysql数据库的表的设计
iBatis入门 -
Mapple_leave:
效果还是挺不错的,谢谢了。
中文简体与繁体的转换 -
arcpad:
JS禁用浏览器退格键
在 Android 操作系统中存在着消息队列的操作,用消息队列可以完成主线程和子线程之间的消息传递,要想完成这些线程的消息操作,则需要使用 Looper 、 Message 和 Handler 类,其关系如下:
所以,我们可以发现, Looper 本身提供的是一个消息队列的集合,而每个消息都可以通过 Handler 增加和取出,而操作 Handler 的对象就是主线程( UI Thread )和子线程(利用 Runable 实现的线程操作类)。
说明:
如果把 Looper 比喻成一个正在排队卖票的队伍,那么每个排队的人就是一个 Message ,而一个维护队伍的管理员就相当于是一个 Handler ,管理员负责通知对外的人进到队列之中等待,也负责通知队列中的人离开队伍。
1 、 Android.os.Message 的主要功能是进行消息的封装,同事可以指定消息的操作形式。
No. |
变量或方法 |
类型 |
描述 |
1 |
Public int what |
变量 |
用于定义此 Message 属性何种操作 |
2 |
Public Object obj |
变量 |
用于定义此 Message 传递的信息数据 |
3 |
Public int arg1 |
变量 |
传递一些整型数据时使用,一般很少用 |
4 |
Public int arg2 |
变量 |
传递一些整型数据时使用,一般很少用 |
5 |
Public Handler getTarget() |
普通 |
取得操作此消息的 Handler 对象 |
在 Message 类中,使用最多的是 what 和 obj 两个变量,通过 what 变量指明一个 Message 所携带的是何种信息,而通过 obj 传递信息
2 、 Message 对象封装了所有的消息,而这些消息的操作需要 android.os.Handler 类完成
No. |
方法 |
类型 |
描述 |
1 |
Public Handler() |
构造 |
创建一个新的 Handler 实例 |
2 |
Public Handler(Looper looper) |
构造 |
使用指定的队列创建一个新的 Handler 实例 |
3 |
Public final Message obtainMessage(int what,Object obj) |
普通 |
获得一个 Messge 对象 |
4 |
Public final Message obtainMessage(int what,Int arg1, int arg2,Object obj) |
普通 |
获得一个 Messge 对象 |
5 |
Public void handleMessage(Message msg) |
普通 |
处理消息的方法,子类要覆写此方法 |
6 |
Public final Boolean hasMessages(int what) |
普通 |
判断是否有指定的 Message |
7 |
Public final boolwan hasMessages(int what,Object obj) |
普通 |
判断是否有指定的 Message |
8 |
Public final void removeMessages(int what) |
普通 |
删除指定的 Message |
9 |
Public final void removeMessages(int what,Object obj) |
普通 |
删除指定的 Message |
10 |
Public final Boolean sendEmptyMessage(int what) |
普通 |
发送一个空消息 |
11 |
Public final Boolean sendEmptyAtTime(Int what, long uptimeMills) |
普通 |
在指定的日期时间发送消息 |
12 |
Public final boolean senEmptyMessageDelayed(int what, long delayMills) |
普通 |
等待指定的时间之后发送消息 |
13 |
Public final boolean sendMessage(Message msg) |
普通 |
发送消息 |
可以发现 Handler 所有的相关操作都是在操作 Message 的,可以向队列中添加 Message ,也可以从队列中删除指定的 Message 。
下面我们来通过一个定时更新文本来做一个范例:
Message01_Activity.java
package com.iflytek.demo; import java.util.Timer; import java.util.TimerTask; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class Message01_Activity extends Activity { private TextView info = null; private static int count = 0; // 表示更新后的记录 private static final int SET = 1; // 操作的what状态 private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { // 判断操作的消息类型 case SET: // 更新组件 Message01_Activity.this.info.setText("XDWANG - " + count++); } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.info = (TextView) super.findViewById(R.id.info); // 取得组件 // 通过任务管理器进行任务调度 Timer timer = new Timer(); //每一秒调度一次 timer.schedule(new MyTask(), 0, 1000); } /** * * @author xdwang * * @create 2012-10-27下午08:11:25 * * @email:xdwangiflytek@gmail.com * * @description 定时调度类 * */ private class MyTask extends TimerTask { @Override public void run() { Message msg = new Message(); // 设置更新 msg.what = SET; // 操作的标记 Message01_Activity.this.myHandler.sendMessage(msg); // 发送消息 } } }
从上面代码我们可以发现是在 Handler 中处理组件内容的,那么为什么不在任务调度器里完成呢?因为子线程不能更新主线程中各个组件的状态。即子线程无法更新组件,那么现在只能采用与之前一样的方式,在子线程之中返回要要操作的消息,而后在主线程之中利用 Handler 处理这些消息,从而实现线程的操作 。
3 、在使用 Handler 处理 Message 时,都需要依靠一个 Looper 通道完成,当用户取得一个 Handler 对象时,实际上都是通过 Looper 完成的,在一个 Activity 类中,会自动帮助用户启动 Looper 对象,而若是在一个用户自定义的类中,则需要手动调用 Looper 类的若干方法,之后才可以正常的启动 Looper 对象,其方法如下:
No. |
方法名称 |
描述 |
1 |
Public static final synchronized Looper getMainLooper() |
取得主线程 |
2 |
Public static final myLooper() |
返回当前的线程 |
3 |
Public static final void prepare() |
初始化 Looper 对象 |
4 |
Public static final void prepareMainLooper() |
初始化主线程 Looper 对象 |
5 |
Public void quit() |
消息队列结束时调用 |
6 |
Public static final void loop() |
启动消息队列 |
下面我们来利用 Looper 做一个范例
Message02_Activity.java:
package com.iflytek.demo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class Message02_Activity extends Activity { private TextView info = null; private static final int SET = 1; // 操作的what状态 private Button but = null; // 操作按钮 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.info = (TextView) super.findViewById(R.id.info); // 取得组件 this.but = (Button) super.findViewById(R.id.but); // 取得组件 this.but.setOnClickListener(new OnClickListenerImpl()); // 单击事件 } private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { Looper looper = Looper.myLooper(); MyHandler myHandler = new MyHandler(looper); myHandler.removeMessages(0); // 表示清空所有的消息 String data = "xdwangiflytek.iteye.com"; // 要传递的消息 Message msg = myHandler.obtainMessage(SET, 1, 1, data); // 创建消息 myHandler.sendMessage(msg); // 发送消息 } } private class MyHandler extends Handler { public MyHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { // 判断操作的消息类型 case SET: // 更新组件 Message02_Activity.this.info.setText(msg.obj.toString()); // 设置文本组件 } } } }
这里如果我们不设置Looper,如下:
private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { MyHandler myHandler = new MyHandler(); myHandler.removeMessages(0); // 表示清空所有的消息 String data = "xdwangiflytek.iteye.com"; // 要传递的消息 Message msg = myHandler.obtainMessage(SET, 1, 1, data); // 创建消息 myHandler.sendMessage(msg); // 发送消息 } } private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { // 判断操作的消息类型 case SET: // 更新组件 Message03_Activity.this.info.setText(msg.obj.toString()); // 设置文本组件 } } }
其效果是一样的。
下面我们来完成一个主线程与子线程之间的数据交换
主线程向子线程发送数据,然后子线程再向主线程发送数据:
Thread01_Activity.java
package com.iflytek.demo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class Thread02_Activity extends Activity { public static final int SETMAIN = 1; // 设置一个what标记 public static final int SETCHILD = 2; // 设置what的标记] private Handler mainHandler, childHandler; private TextView msg = null; private Button but; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.msg = (TextView) super.findViewById(R.id.msg); this.but = (Button) super.findViewById(R.id.but); this.mainHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case SETMAIN: Thread02_Activity.this.msg.setText("主线程接收数据:" + msg.obj.toString()); break; } } }; new Thread(new ChildThread(), "Child Thread").start(); this.but.setOnClickListener(new OnClickListenerImpl()); } private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { // 是将信息发送到子线程之中 //因为线程的状态不固定,所以这里需要一个判断 if (Thread02_Activity.this.childHandler != null) { Message childMsg = Thread02_Activity.this.childHandler .obtainMessage(); // 创建消息 childMsg.obj = Thread02_Activity.this.mainHandler.getLooper() .getThread().getName() + " --> Hello XDWANG ."; childMsg.what = SETCHILD; Thread02_Activity.this.childHandler.sendMessage(childMsg); } } } /** * * @author xdwang * * @create 2012-10-27下午08:31:25 * * @email:xdwangiflytek@gmail.com * * @description 子线程的线程类 * */ class ChildThread implements Runnable { @Override public void run() { Looper.prepare();//准备好一个Looper对象 Thread02_Activity.this.childHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case SETCHILD: // 子线程接收主线程发送来的消息 System.out.println("*** Main Child Message : " + msg.obj); // 输出数据 Message toMain = Thread02_Activity.this.mainHandler .obtainMessage(); toMain.obj = "\n\n[B]这是子线程发送给主线程的信息:" + super.getLooper().getThread().getName(); toMain.what = SETMAIN; Thread02_Activity.this.mainHandler.sendMessage(toMain); break; } } }; Looper.loop(); // 创建消息队列 } } @Override protected void onDestroy() { super.onDestroy(); //结束子线程的操作队列 Thread02_Activity.this.childHandler.getLooper().quit(); } }
打印:
10-27 21:04:07.165: I/System.out(4449): *** Main Child Message : main --> Hello XDWANG .
下面我们再以一个时钟显示来看看
前面我们说过时钟的组件,但是当时没有时间的说明,下面我们来写一个这样的时钟
main.xml
<?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"> <AnalogClock android:id="@+id/myAnalogClock" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
AnalogClockThread_Activity.java
package com.iflytek.demo; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class AnalogClockThread_Activity extends Activity { private TextView info = null; private static final int SET = 1; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case SET: AnalogClockThread_Activity.this.info.setText("当前时间为:" + msg.obj.toString()); break; } } }; private class ClockThread implements Runnable { @Override public void run() { while (true) { // 一直更新 Message msg = AnalogClockThread_Activity.this.handler .obtainMessage(AnalogClockThread_Activity.SET, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .format(new Date())); AnalogClockThread_Activity.this.handler.sendMessage(msg); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.info = (TextView) super.findViewById(R.id.info); new Thread(new ClockThread()).start(); } }
进度条组件:ProgressBar
main.xml
<?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"> <ProgressBar android:id="@+id/myprobarA" android:visibility="gone" style="?android:attr/progressBarStyle" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ProgressBar android:id="@+id/myprobarB" android:visibility="gone" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ProgressBar android:id="@+id/myprobarC" android:visibility="gone" style="?android:attr/progressBarStyleHorizontal" android:max="120" android:progress="0" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ProgressBar android:id="@+id/myprobarD" android:visibility="gone" style="?android:attr/progressBarStyleLarge" android:max="120" android:progress="50" android:secondaryProgress="70" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ProgressBar android:id="@+id/myprobarE" android:visibility="gone" style="?android:attr/progressBarStyleSmall" android:max="120" android:progress="50" android:secondaryProgress="70" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/mybut" android:text="显示进度条" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
属性说明:
android:visibility="gone":隐藏进度条 android:max="120":设置最大进度 android:progress="50":设置当前进度 android:secondaryProgress="70":设置第二进度条当前值
ProgressBar_Activity.java:
package com.iflytek.demo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; public class ProgressBar_Activity extends Activity { private static final int STOP = 1; private static final int CONTINUE = 2; private ProgressBar myprobarA, myprobarB, myprobarC, myprobarD, myprobarE; private Button mybut; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.myprobarA = (ProgressBar) super.findViewById(R.id.myprobarA); this.myprobarB = (ProgressBar) super.findViewById(R.id.myprobarB); this.myprobarC = (ProgressBar) super.findViewById(R.id.myprobarC); this.myprobarD = (ProgressBar) super.findViewById(R.id.myprobarD); this.myprobarE = (ProgressBar) super.findViewById(R.id.myprobarE); this.mybut = (Button) super.findViewById(R.id.mybut); this.myprobarA.setIndeterminate(false); // 不确定模式 this.myprobarB.setIndeterminate(false); // 不确定模式 this.myprobarC.setIndeterminate(true); // 确定模式 this.myprobarD.setIndeterminate(false); // 不确定模式 this.myprobarE.setIndeterminate(false); // 不确定模式 this.mybut.setOnClickListener(new OnClickListenerImpl()); // 单击事件 } private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { ProgressBar_Activity.this.myprobarB.setSecondaryProgress(50); ProgressBar_Activity.this.myprobarA.setVisibility(View.VISIBLE); ProgressBar_Activity.this.myprobarB.setVisibility(View.VISIBLE); ProgressBar_Activity.this.myprobarC.setVisibility(View.VISIBLE); ProgressBar_Activity.this.myprobarD.setVisibility(View.VISIBLE); ProgressBar_Activity.this.myprobarE.setVisibility(View.VISIBLE); ProgressBar_Activity.this.myprobarA.setMax(120); ProgressBar_Activity.this.myprobarB.setMax(120); ProgressBar_Activity.this.myprobarA.setProgress(0); ProgressBar_Activity.this.myprobarB.setProgress(0); new Thread(new Runnable() { @Override public void run() { int count = 0; // 保存当前进度的值 for (int i = 0; i < 10; i++) { count = (i + 1) * 20; // 进度的增长快一些 try {// 每次操作延迟500MS Thread.sleep(500); } catch (InterruptedException e) { } if (i == 6) { // 正好增长到120 Message m = new Message(); m.what = ProgressBar_Activity.STOP; // 停止 ProgressBar_Activity.this.myMessageHandler .sendMessage(m);// 停止 } else { Message m = new Message(); m.what = ProgressBar_Activity.CONTINUE; m.arg1 = count; ProgressBar_Activity.this.myMessageHandler .sendMessage(m); } } } }).start(); } } private Handler myMessageHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case ProgressBar_Activity.STOP: ProgressBar_Activity.this.myprobarA.setVisibility(View.GONE); ProgressBar_Activity.this.myprobarB.setVisibility(View.GONE); ProgressBar_Activity.this.myprobarC.setVisibility(View.GONE); ProgressBar_Activity.this.myprobarD.setVisibility(View.GONE); ProgressBar_Activity.this.myprobarE.setVisibility(View.GONE); Thread.currentThread().interrupt(); break; case ProgressBar_Activity.CONTINUE: if (!Thread.currentThread().isInterrupted()) { // 线程没有中断 ProgressBar_Activity.this.myprobarA.setProgress(msg.arg1); ProgressBar_Activity.this.myprobarB.setProgress(msg.arg1); ProgressBar_Activity.this.myprobarC.setProgress(msg.arg1); ProgressBar_Activity.this.myprobarD.setProgress(msg.arg1); ProgressBar_Activity.this.myprobarE.setProgress(msg.arg1); } break; } } }; }
效果图:
异步处理工具类: AsyncTask
上面我们了解了主线程与子线程之间的通信主要依靠 Handler 完成,但子线程无法直接对主线程的组件进行更新,而如果所有的开发都分别定义若干个子线程的操作对象,则这多个对象同时对主线程操作就会非常满分,为了解决这个问题,在 Android1.5 之后专门提供了一个 andorid.os.AsyncTask (非同步任务)类,可以通过此类完成非阻塞的操作类,该类的功能与 Handler 类似,可以在后台进行操作之后更新主线程的 UI ,但其使用比 Handler 要容易的多。
通过此类的定义可以发现,在 AsyncTask 类中要通过泛型指定 3 个参数,作用分别是:
Params :启动时需要的参数类型,如每次操作的休眠时间为 Integer ;
Progress :后台执行任务的百分比,如进度条需要传递的是 Integer ;
Result :后台执行完毕之后返回的信息,如完成数据信息显示传递的是 String ;
常用方法:
No. |
方法 |
描述 |
1 |
Public final Boolean cancel(Boolean mayInterruptIfRunning)) |
指定是否取消当前线程操作 |
2 |
Public final AsyncTask<Params,Progress,Result> execute(Params… params) |
执行 AsyncTask 操作 |
3 |
Public final Boolean isCancelled() |
判断子线程是否被取消 |
4 |
Protected final void publishProgress( Progress… values) |
更新线程进度 |
5 |
Protected abstract Result doInBackground( Params… params) |
在后台完成任务执行,可以调用 publishProgress() 方法更新线程进度 |
6 |
Protectes void onProgressUpdate( Progress… values) |
在主线程中执行,用于显示任务的进度 |
7 |
Protectes void onPreExecute() |
在主线程中执行,在 doInBackground() 之前执行 |
8 |
Protectes void onPostExecute(Result result) |
在主线程中执行,方法参数为任务执行结果 |
9 |
Protectes void onCancelled() |
主线程中执行,在 cancel() 方法之后执行 |
下面我们通过 AsyncTask 来实现进度条
main.xml
<?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"> <ProgressBar android:id="@+id/bar" android:layout_width="fill_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal"/> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
AsyncTask_Activity.java
package com.iflytek.demo; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.ProgressBar; import android.widget.TextView; public class AsyncTask_Activity extends Activity { private ProgressBar progressBar = null; private TextView info = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.progressBar = (ProgressBar) super.findViewById(R.id.bar); this.info = (TextView) super.findViewById(R.id.info); ChildUpdate child = new ChildUpdate(); //每次休眠100毫秒 child.execute(100); } // 每次处理后台进度的类型是Integer、更新之后的数值Integer,最后的结果返回的是字符串 private class ChildUpdate extends AsyncTask<Integer, Integer, String> { @Override protected void onPostExecute(String result) { AsyncTask_Activity.this.info.setText(result); } @Override protected void onProgressUpdate(Integer... values) { // 每次更新之后的内容 AsyncTask_Activity.this.info.setText("当前的进度值是:" + String.valueOf(values[0])); } @Override protected String doInBackground(Integer... params) { // 每次的进度处理,可以更新UI组件 for (int x = 0; x < 100; x++) { AsyncTask_Activity.this.progressBar.setProgress(x); // 设置进度 this.publishProgress(x); // 更新,调用更新操作 try {// 延迟的操作由外部决定 Thread.sleep(params[0]); } catch (InterruptedException e) { } } return "执行完毕"; } } }
从上我们可以发现这个组件完全融合了Handler和Message的功能所完成。
下面我们再做一个简单的文件管理器
main.xml:
<?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>
file_list.xml:
<?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="fill_parent"> <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>
AsyncTaskListFile_Activity.java
package com.iflytek.demo; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.SimpleAdapter; public class AsyncTaskListFile_Activity extends Activity { private List<Map<String, Object>> allFileItems = new ArrayList<Map<String, Object>>(); private SimpleAdapter simpleAdapter = null; private ListView listView = null; private ListFileThread listFileThread = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.listView = (ListView) super.findViewById(R.id.list); File filePath = new File(java.io.File.separator); // 从根目录下开始列出 this.listView.setOnItemClickListener(new OnItemClickListenerImpl()); this.listFileThread = new ListFileThread(); this.listFileThread.execute(filePath); } private class OnItemClickListenerImpl implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { File currFile = (File) AsyncTaskListFile_Activity.this.allFileItems .get(position).get("name"); if (currFile.isDirectory()) { // 当前是一个目录 AsyncTaskListFile_Activity.this.allFileItems = new ArrayList<Map<String, Object>>(); AsyncTaskListFile_Activity.this.listFileThread = new ListFileThread(); AsyncTaskListFile_Activity.this.listFileThread.execute(currFile); } } } private class ListFileThread 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]); AsyncTaskListFile_Activity.this.allFileItems.add(fileItem); AsyncTaskListFile_Activity.this.simpleAdapter = new SimpleAdapter( AsyncTaskListFile_Activity.this, AsyncTaskListFile_Activity.this.allFileItems, R.layout.file_list, new String[] { "img", "name" }, new int[] { R.id.img, R.id.name }); AsyncTaskListFile_Activity.this.listView .setAdapter(AsyncTaskListFile_Activity.this.simpleAdapter); } @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()); AsyncTaskListFile_Activity.this.allFileItems.add(fileItem); } if (params[0].isDirectory()) { // 是文件夹 File tempFile[] = params[0].listFiles(); if (tempFile != null) { for (int x = 0; x < tempFile.length; x++) { this.publishProgress(tempFile[x]); } } } return "文件已列出"; } } }
效果图:
发表评论
-
This version of ADT requires android SDK
2013-07-25 16:45 1594Windows系统下用Eclipse开发工具开发An ... -
Android学习13-----网络通信(4) WebView组件
2012-11-27 09:18 2514WebView 是一个开发的浏览 ... -
Android学习13-----网络通信(3) 与Web Service进行通讯
2012-11-26 09:40 1895这里我们的WebService使用xFire开发。 ... -
Android学习13-----网络通信(2) 与Socket交换数据
2012-11-23 09:11 3309对于网络开发而言,最常用的交互模式:WebService、We ... -
Android学习13-----网络通信(1) 与WEB服务器交换数据
2012-11-22 09:11 2196与Web服务器交互: 如果手机要想与 web ... -
Android学习11-----多媒体技术(5) 媒体录制
2012-11-16 08:10 1894在Android中通过android.media ... -
Android学习11-----多媒体技术(4) 使用摄像头拍照,多点触控
2012-11-15 08:37 2886一、摄像头拍照 前面说媒体播放 时了解了 ... -
Android学习11-----多媒体技术(3) 媒体播放
2012-11-14 08:25 1415在 Androi ... -
Android学习11-----多媒体技术(2) Animation
2012-11-13 08:47 1995一、渐变动画, Tweened Animation ... -
Android学习11-----多媒体技术(1) 绘制简单图形,Bitmap,Matrix
2012-11-12 08:48 1626一、绘制简单图 ... -
Android学习12-----手机服务(4) 传感器
2012-11-19 09:13 2018传感器一般用于游戏中,在 Android 系统中为 ... -
Android学习12-----手机服务(1) 取得电池电量和声音服务:AudioManager
2012-11-18 11:18 3507一、取得电池电量信息 ... -
Android学习10-----Android组件通信 (8) 桌面显示组件:AppWidget
2012-11-02 08:36 2038一、 AppWidget 在使用 Androi ... -
Android学习10-----Android组件通信 (7) 广播机制:Broadcast
2012-11-01 08:43 1518一、 广播: 广播也是一种信息的发送机制,在 ... -
Android学习10-----Android组件通信 (6) PendingIntent
2012-10-31 08:20 2261Intent 的主要功能是表示用 ... -
Android学习10-----Android组件通信 (5) Service
2012-10-30 08:25 1737Service 基本组成: ... -
Android学习10-----Android组件通信 (3) ActivityGroup
2012-10-26 08:23 2317导航栏在 Android 中的应用是很常见的,前面 ... -
Android学习10-----Android组件通信 (2) Activity生命周期
2012-10-25 08:16 1287Activity 是整个 Android 平台的基 ... -
Android学习10-----Android组件通信 (1) Intent
2012-10-24 08:43 2011在一个项目之中,会由多个 Activity ... -
Android判断是否有网络连接
2013-04-25 16:34 1441Android中判断有时候因为功能的需求,需要判断是否有网络 ...
相关推荐
`android-support-v4`库中的BroadcastReceiver和PendingIntent类提供了与原生API相匹配的功能,使得开发者能在低版本的Android上使用这些组件进行事件监听和跨组件通信。 **Preference支持** Preference类是用于...
在Android平台上进行串口通信开发是一项重要的技能,尤其是在嵌入式设备、物联网(IoT)应用或者需要与硬件设备交互的场景中。Google官方提供的`android-serialport-api`库就是为了方便开发者实现这一功能。这个库允许...
开发者可以通过研究这些源代码来学习如何在Android平台上实现XMPP协议,以及Beem是如何利用Asmack实现其复杂的通信功能的。这不仅对理解Asmack的工作原理有益,也有助于自定义或扩展Beem应用程序。
1. `app`目录:这是Android应用的主要代码库,包含Activity、Service、BroadcastReceiver等核心组件。 2. `libs`目录:存放了项目所需的第三方库,如蓝牙通信库、固件升级库等。 3. `res`目录:包含了应用的资源文件...
4. **EventBus**:Spring for Android提供了一个事件总线,允许组件之间进行解耦的通信。这种设计模式可以帮助我们避免Activity和Fragment之间的直接调用,提升应用的结构清晰度。 5. **Android Context管理**:...
2. **Android Platform Tools**:这是SDK中的一个重要组成部分,包括adb(Android Debug Bridge)、fastboot和其他用于设备通信的工具。adb是开发者与Android设备交互的主要手段,可用于安装应用、调试、传输文件等...
4. **Eclipse ADT Plugin**: 虽然在描述中未提及,但考虑到1.5_r3的年代,当时Android开发主要依赖Eclipse IDE,ADT(Android Developer Tools)插件是必不可少的,它允许开发者在Eclipse中创建、编辑、调试和发布...
2. **Android SDK Platform Tools**:包括adb(Android Debug Bridge)、fastboot等,用于设备通信、安装应用、数据备份等。 3. **Android SDK Build-Tools**:用于构建APK,包含aapt(Android Asset Packaging Tool...
总结来说,"Android-nRF-Toolbox-master"不仅是一个实用的开发工具,更是学习和研究BLE通信、Android应用开发和Nordic芯片应用的宝贵资源。通过深入研究源代码,开发者可以掌握BLE通信的核心技术,为开发自己的BLE...
Android SDK(Software Development Kit)是开发Android应用必不可少的工具集,它包含了编写、调试和运行Android应用程序所需的各种组件。在Windows环境下,这个压缩包“android-sdk-windows.zip”提供了全面的SDK...
《Android-Tool-Log:Android轻量级日志组件详解》 在Android应用开发中,日志记录是一项不可或缺的功能,它能帮助开发者调试程序、排查问题。本文将深入探讨名为"Android-Tool-Log"的轻量级日志组件,其特点在于...
本示例“Android-netty和socket通信的demo”将展示如何在Android平台上利用Netty进行网络通信,与传统的Socket编程相结合,实现更加灵活和高效的通信机制。 首先,理解Netty的基本概念是非常重要的。Netty是一个...
在Android开发中,`android-support-v4`库是一个至关重要的组件,它提供了对早期Android版本的API兼容性支持。这个库包含了大量实用的功能,使得开发者能够编写与Android 2.1(API级别7)及更高版本兼容的应用程序,...
Binder是Android系统中的核心组件,它是Android系统实现进程间通信(IPC,Inter-Process Communication)的主要方式。Binder机制允许不同进程的组件之间进行数据交换和功能调用,就像它们在同一进程中一样,实现了...
- `system/core` 存放了 Android 系统的核心组件,如 init 进程、内核接口、JNI 头文件等。 3. **Android 源码学习路径**: - 首先,开发者应熟悉 Android 开发的基本概念,如 Activity 生命周期、Intent 机制等...
在本文中,我们将深入探讨android-support-v4源码,了解其内部机制和关键组件,以期为开发者提供更全面的理解。 首先,我们来看一下`android-support-v4-master`这一压缩包中的主要内容。这通常是Android项目的一个...
"android-platform-tools-28.0.1"是Android开发者必备的一个组件,它属于Android Software Development Kit (SDK) 的一部分,主要包含了用于Android应用开发和设备管理的一系列命令行工具。这个版本对应的是Android ...
《Android-nRF-Toolbox:探索蓝牙低功耗(BLE)在Android系统中的应用》 在移动设备领域,蓝牙低功耗(Bluetooth Low Energy,简称BLE或Bluetooth LE)技术已经广泛应用,尤其在物联网(IoT)场景下,其低功耗、高...
这个版本的SDK包含了开发Android应用所需的所有基本组件,对于学习和实践疯狂Android讲义2至关重要。 首先,让我们了解Android SDK的核心组件: 1. **SDK Manager**: 这是SDK的主管理工具,用于下载和更新Android...
SCI-android-usb-driver-jungo驱动包包含了以下关键组件: 1. **USB主机驱动**:允许Android设备作为USB主机,连接并控制其他USB设备,如外置存储、相机、打印机等。 2. **USB设备驱动**:当Android设备作为USB...