activity启动模式Word格式文档下载.docx
- 文档编号:20589545
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:19
- 大小:23.01KB
activity启动模式Word格式文档下载.docx
《activity启动模式Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《activity启动模式Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
以后遇到这样的异常抛出时就要知道怎么回事了!
2.2MessageQueue
在单线程模型下,为了解决类似的问题,Android设计了一个MessageQueue(消息队列),线程间可以通过该MessageQueue并结合Handler和Looper组件进行信息交换。
下面将对它们进行分别介绍:
1.Message
Message消息,理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。
2.Handler
Handler处理者,是Message的主要处理者,负责Message的发送,Message内容的执行处理。
后台线程就是通过传进来的Handler对象引用来sendMessage(Message)。
而使用Handler,需要implement该类的
handleMessage(Message)方法,它是处理这些Message的操作内容,例如UpdateUI。
通常需要子类化Handler来实现handleMessage方法。
3.MessageQueue
MessageQueue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
每个messagequeue都会有一个对应的Handler。
Handler会向messagequeue通过两种方法发送消息:
sendMessage或post。
这两种消息都会插在messagequeue队尾并按先进先出执行。
但通过这两种方法发送的消息执行的方式略有不同:
通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;
而通过post方法发送的是一个runnable对象,则会自己执行。
4.Looper
Looper是每条线程里的MessageQueue的管家。
Android没有Global的MessageQueue,而Android会自动替主线程(UI线程)建立MessageQueue,但在子线程里并没有建立MessageQueue。
所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper()得到当前线程的Looper就有可能为NULL。
对于子线程使用Looper,APIDoc提供了正确的使用方法:
1.class
LooperThread
extends
Thread
{
2.
3.
public
Handler
mHandler;
4.
5.
6.
7.
void
run()
8.
9.
Looper.prepare();
//创建本线程的Looper并创建一个MessageQueue
10.
11.
12.
13.
14.
mHandler
=
new
Handler()
15.
16.
17.
handleMessage(Message
msg)
18.
19.
//
process
incoming
messages
here
20.
21.
}
22.
23.
};
24.
25.
26.
27.
Looper.loop();
//开始运行Looper,监听Message
Queue
28.
29.
30.
31.}
32.
这个Message机制的大概流程:
1.在Looper.loop()方法运行开始后,循环地按照接收顺序取出MessageQueue里面的非NULL的Message。
2.一开始MessageQueue里面的Message都是NULL的。
当Handler.sendMessage(Message)到MessageQueue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。
随后Looper取出了那个Message,则调用该Message的target指向的Hander的dispatchMessage函数对Message进行处理。
在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:
1)Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;
2)Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;
3)处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
由此可见,我们实现的handleMessage方法是优先级最低的!
3.Handler处理完该Message(updateUI)后,Looper则设置该Message为NULL,以便回收!
在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终谁来执行处理信息之类的,个人理解是最简单的方法——判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行!
1.当Handler对象的构造函数的参数为空,则为当前所在线程的Looper;
2.
Looper.getMainLooper()得到的是主线程的Looper对象,Looper.myLooper()得到的是当前线程的Looper对象。
现在来看一个例子,模拟从网络获取数据,加载到ListView的过程:
1.public
class
ListProgressDemo
ListActivity
@Override
onCreate(Bundle
savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.listprogress);
13.
14.
15.
((Button)
findViewById(R.id.load_Handler)).setOnClickListener(new
View.OnClickListener(){
onClick(View
view)
data
null;
ArrayList<
String>
();
adapter
31.
33.
showDialog(PROGRESS_DIALOG);
34.
35.
ProgressThread(handler,
data).start();
36.
37.
38.
39.
});
40.
41.
42.
43.
44.
45.
46.
47.
protected
Dialog
onCreateDialog(int
id)
48.
49.
switch(id)
50.
51.
case
PROGRESS_DIALOG:
52.
53.
return
ProgressDialog.show(this,
"
54.
55.
Loading.
Please
wait..."
true);
56.
57.
58.
59.
default:
60.
61.
62.
63.
64.
65.
66.
67.
private
ProgressThread
68.
69.
70.
71.
handler;
72.
73.
data;
74.
75.
76.
77.
ProgressThread(Handler
handler,
data)
78.
79.
this.handler
80.
81.
this.data
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
for
(int
i=0;
i<
8;
i++)
92.
93.
data.add("
ListItem"
);
//后台数据处理
94.
95.
try
96.
97.
Thread.sleep(100);
98.
99.
}catch(InterruptedException
e)
100.
101.
102.
103.
Message
msg
handler.obtainMessage();
104.
105.
Bundle
b
Bundle();
106.
107.
b.putInt("
state"
STATE_ERROR);
108.
109.
msg.setData(b);
110.
111.
handler.sendMessage(msg);
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
STATE_FINISH);
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
此处甚至可以不需要设置Looper,因为Handler默认就使用当前线程的Looper
138.
139.
final
handler
Handler(Looper.getMainLooper())
{
140.
141.
142.
143.
144.
//处理Message,更新ListView
145.
146.
int
state
msg.getData().getInt("
147.
148.
switch(state){
149.
150.
STATE_FINISH:
151.
152.
dismissDialog(PROGRESS_DIALOG);
153.
154.
Toast.makeText(getApplicationContext(),
155.
156.
加载完成!
157.
158.
Toast.LENGTH_LONG)
159.
160.
.show();
161.
162.
163.
164.
ArrayAdapter<
(getApplicationContext(),
165.
166.
android.R.layout.simple_list_item_1,
167.
168.
169.
170.
171.
172.
setListAdapter(adapter);
173.
174.
175.
176.
break;
177.
178.
179.
180.
STATE_ERROR:
181.
182.
183.
184.
185.
186.
处理过程发生错误!
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
adapter;
225.
226.
227.
228.
229.
230.
static
PROGRESS_DIALOG
1;
231.
232.
STATE_FINISH
233.
234.
STATE_ERROR
-1;
235.
236.}
237.
这个例子,我自己写完后觉得还是有点乱,要稍微整理才能看明白线程间交互的过程以及数据的前后变化。
随后了解到AsyncTask类,相应修改后就很容易明白了!
2.3AsyncTask
AsyncTask版:
1.((Button)
findViewById(R.id.load_AsyncTask)).setOnClickListener(new
//显示ProgressDialog放到AsyncTask.onPreExecute()里
//showDialog(PROGRESS_DIALOG);
ProgressTask
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- activity 启动 模式