- 浏览: 660965 次
- 性别:
- 来自: 安徽
文章分类
- 全部博客 (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 1531Windows系统下用Eclipse开发工具开发An ... -
Android学习13-----网络通信(4) WebView组件
2012-11-27 09:18 2447WebView 是一个开发的浏览 ... -
Android学习13-----网络通信(3) 与Web Service进行通讯
2012-11-26 09:40 1849这里我们的WebService使用xFire开发。 ... -
Android学习13-----网络通信(2) 与Socket交换数据
2012-11-23 09:11 3259对于网络开发而言,最常用的交互模式:WebService、We ... -
Android学习13-----网络通信(1) 与WEB服务器交换数据
2012-11-22 09:11 2152与Web服务器交互: 如果手机要想与 web ... -
Android学习11-----多媒体技术(5) 媒体录制
2012-11-16 08:10 1838在Android中通过android.media ... -
Android学习11-----多媒体技术(4) 使用摄像头拍照,多点触控
2012-11-15 08:37 2823一、摄像头拍照 前面说媒体播放 时了解了 ... -
Android学习11-----多媒体技术(3) 媒体播放
2012-11-14 08:25 1371在 Androi ... -
Android学习11-----多媒体技术(2) Animation
2012-11-13 08:47 1948一、渐变动画, Tweened Animation ... -
Android学习11-----多媒体技术(1) 绘制简单图形,Bitmap,Matrix
2012-11-12 08:48 1554一、绘制简单图 ... -
Android学习12-----手机服务(4) 传感器
2012-11-19 09:13 1982传感器一般用于游戏中,在 Android 系统中为 ... -
Android学习12-----手机服务(1) 取得电池电量和声音服务:AudioManager
2012-11-18 11:18 3414一、取得电池电量信息 ... -
Android学习10-----Android组件通信 (8) 桌面显示组件:AppWidget
2012-11-02 08:36 1984一、 AppWidget 在使用 Androi ... -
Android学习10-----Android组件通信 (7) 广播机制:Broadcast
2012-11-01 08:43 1472一、 广播: 广播也是一种信息的发送机制,在 ... -
Android学习10-----Android组件通信 (6) PendingIntent
2012-10-31 08:20 2196Intent 的主要功能是表示用 ... -
Android学习10-----Android组件通信 (5) Service
2012-10-30 08:25 1665Service 基本组成: ... -
Android学习10-----Android组件通信 (3) ActivityGroup
2012-10-26 08:23 2259导航栏在 Android 中的应用是很常见的,前面 ... -
Android学习10-----Android组件通信 (2) Activity生命周期
2012-10-25 08:16 1240Activity 是整个 Android 平台的基 ... -
Android学习10-----Android组件通信 (1) Intent
2012-10-24 08:43 1913在一个项目之中,会由多个 Activity ... -
Android判断是否有网络连接
2013-04-25 16:34 1398Android中判断有时候因为功能的需求,需要判断是否有网络 ...
相关推荐
Android组件通信与广播消息Android组件通信与广播消息Android组件通信与广播消息Android组件通信与广播消息
了解使用Intent进行组件通信的原理 掌握使用Intent启动Activity的方法 掌握获取Activity返回值的方法 了解Intent过滤器的原理与匹配机制 掌握发送和接收广播消息的方法
android开发中组件之间通信-广播的方式总结。
作者简介 -10 前言 -9 目录 -4 第1章 Android简介 1 1.1 一些背景信息 2 1.1.1 不远的过去 2 1.1.2 未来的前景 2 1.2 对Android的误解 3 1.3 开放的移动开发平台 3 1.4 自带的Android应用程序 4 1.5 Android ...
android各组件详解- Service
Android组件间通信库,代替Intent和BroadcastReceiver,简单易用,源码以及jar提供下载
Android组件通信与广播消息,Intent与Intent-filter详解
Android安全开发基础--10--图形界面(UI)和碎片(Fragment)(上).pdf Android安全开发基础--11--图形界面(UI)和碎片(Fragment)(下).pdf Android安全开发基础--12--持久化技术.pdf Android安全开发基础--13-...
----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...
ARetrofit一款优秀的Android组件化框架(皮一下^_^开心),可以轻松实现跨module通信。这里之所以使用Retrofit作为后缀命名主要是为了尊重retrofit大神的架构思路,其目的降低开发者的学习和使用成本。 如果你正在对...
简化Android组件之间的共享字段和通信,以及可识别生命周期的自定义范围
WanAndroid【已停止维护】 前言 一款含有有丰富Android开发文章的App,内容每天都会更新。 原网站 http://www.wanandroid.com ,数据内容源至...EventBus --组件间通信 Bmob --云后台 项目进度 [x] 完成登录注册
AndroidBaseFrameMVVM 是一个Android工程框架,所使用技术栈为:组件化、Kotlin、MVVM、Jetpack、Repository、Kotlin-Coroutine-Flow,本框架既是一个可以开箱即用的工程框架基础层,也是一个很好的学习资源,文档...
Android-react-native-ble-manager.zip,react native ble通信模块,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核之上构建的,具有安全性优势。
一款高效的组件间通信方案,0反射,仅需简单配置,即可方便的进行组件间通信
基于组件间通信的Android应用安全分析,黄炎裔,郭燕慧,近年来,Android恶意应用逐渐出现直接或间接利用其它应用达到不法目的的现象,因此对于Android应用的安全研究也逐渐由单个应用转向多�
这些年我们在微服务与消息中间件在网络通信上解决过很多问题,积累了很多经验,并持续的进行着优化和完善,我们希望能把总结出的解决方案沉淀到 SOFABolt 这个基础组件里,让更多的使用网络通信的场景能够统一受益。...
模块组件和通用组件,可分为业务组件和UI组件等等,比如下拉刷新可作为通用ui组件,供多个项目调用,登录模块或者网络模块,可作为通用业务组件存在,供多个项目使用。 在项目开发中,讲项目拆分为不同的组件,开发...
module间Activity相互启动,传值方面直接看activityrouter官方文档https://github.com/mzule/ActivityRouter