Android 进程和线程模型-2

上一篇 / 下一篇  2012-10-09 11:05:45 / 个人分类:杂谈

6G K0m#M v0  Message Queue:

|%I*N$N2`7K _j)H|0

MQ$p,M}p2F^)r0  Message Queue是一个消息队列,用来存放通过Handler发布的消息。Android在第一次启动程序时会默认会为UI thread创建一个关联的消息队列,可以通过Looper.myQueue()得到当前线程的消息队列,用来管理程序的一些上层组 件,activities,broadcast receivers 等等。你可以在自己的子线程中创建Handler与UI thread通讯。

jx"S$^0]0

b3@V)M ug [0  通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。每个Handler都会与唯一的一个线程以及该线程的消息队列管理。

Y0_x*Sb)g^#[e0

E9u D6Ez b0  Looper扮演着一个Handler和消息队列之间通讯桥梁的角色。程序组件首先通过Handler把消息传递给Looper,Looper 把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。

~cFa]-kj,M051Testing软件测试网 Z,Dex4x.I

  实例如下:51Testing软件测试网jhU:D] nx

51Testing软件测试网)DTV5h UID?z

51Testing软件测试网 Fa*e aT]u

51Testing软件测试网"e D@(Ngx-l

public void onCreate(Bundle savedInstanceState) { 
Idvr {1q vi0   super.onCreate(savedInstanceState); 
%uuv&k |,LF0   setContentView(R.layout.main); 
$n}K'RS!V0   editText = (EditText) findViewById(R.id.weather_city_edit); 
s;a7stG u,Q0   Button button = (Button) findViewById(R.id.goQuery); 
^#a%U6Hkz0   button.setOnClickListener(this); 
51Testing软件测试网 pQ`/hXg!T L

51Testing软件测试网L-f'zt5~l y&A+I%F

   Looper looper = Looper.myLooper();  //得到当前线程的Looper实例,由于当前线程是UI线程也可以通过Looper.getMainLooper()得到 51Testing软件测试网{yB^0B3[
    messageHandler = new MessageHandler(looper);  //此处甚至可以不需要设置Looper,因为 Handler默认就使用当前线程的Looper 
_P,T5q:j0}
51Testing软件测试网(X2zwr(f \1G

51Testing软件测试网8VC9Fj wf)X

public void onClick(View v) { 
p-pP~S"nSF0   new Thread() { 51Testing软件测试网`g,Tm&Q@
      public void run() { 51Testing软件测试网$WE6A2~9h|/c
          Message message = Message.obtain(); 
\XXhV0          message.obj = "abc"; 
5g.c*|q.fj9@'u0          messageHandler.sendMessage(message);  //发送消息
QXZ,_9Ay4zq9M6dN3di0       } 51Testing软件测试网2K,D{@`(RS:DL0w%U
   }.start(); 
,OuTW;pm v0}
51Testing软件测试网 a$Q5MnQ[:@N

Hjd mj,n0Handler messageHandler = new Handler { 
ucPg%~}6P'gg0   public MessageHandler(Looper looper) { 
Bje'H}nN*G0      super(looper); 
hWw7k'Ye;x-OH0  }
h-b"wdo0   public void handleMessage(Message msg) { 
p6c)j;tIO8d0      setTitle((String) msg.obj); 51Testing软件测试网(N.|0W)v2C:N%z5O8l8{D`;Sj
   }
8kb(o/`2iV*KQ0}
51Testing软件测试网t`K;wE~:J

51Testing软件测试网U(HxF6i0j_

  对于这个实例,当这个activity执行完onCreate,onStart,onResume后,就监听UI的各种事件(如Click点击事件)和消息(如Handler Message)。51Testing软件测试网:i GI2j%a"Q

51Testing软件测试网h0z'SD1OE.B

  当我们点击一个按钮后,启动一个线程,线程执行结束后,通过handler发送一个消息,由于这个handler属于UI线程,因此这个消息也 发送给UI线程,然后UI线程又把这个消息给handler处理,而这个handler是UI线程创造的,他可以访问UI组件,因此就更新了页面。

.l;zS |:E5e0

1ty X/A3U+\3k0  由于通过handler需要自己管理线程类,如果业务稍微复杂,代码看起来就比较混乱,因此android提供了AsyncTask类来解决此问题。51Testing软件测试网"A n/]&p$x0D!?

51Testing软件测试网"^H;bO.N!dK![

  AsyncTask51Testing软件测试网0m9~9`4XsQd

51Testing软件测试网N[^3z"d*I||N@

  首先继承一下此类,实现以下若干方法:

y_{*R5u _Dt1X0

'u%c-D3Z s%jA0  1)onPreExecute(),该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。51Testing软件测试网M"^8j Rrc

A!B~OY0W5nl0  2)doInBackground(Params...),将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。51Testing软件测试网 JX[H(kq

51Testing软件测试网/|P F i&~8t

  可以调用publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。51Testing软件测试网 R;W9~ HY9Lri

51Testing软件测试网K7i THpO'c|:[

  3)onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。51Testing软件测试网*_!IXv&U7yN_O3l P

R9n?!T4h0  4)onPostExecute(Result),在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.51Testing软件测试网3TGZLT

;j8|NX^0  使用时需要遵循以下规则:51Testing软件测试网j.a)VsqyaEb|

51Testing软件测试网-r6rf"p.iJ3]g

  1)Task的实例必须在UI thread中创建51Testing软件测试网\1P4k2|h

nq m2RL j@#C0  2)execute方法必须在UI thread中调用51Testing软件测试网Ro yx(s q*|G

,LR/y-AU!h8Y2F8VL0  3)不要手动的调用这些方法,只调用execute即可51Testing软件测试网!l5jz3o,Pc

51Testing软件测试网*[%J%WR0rA6IF

  4)该task只能被执行一次,否则多次调用时将会出现异常51Testing软件测试网:k#R&NX3n!f @

'Fm1Ud{(U"N9x0  示例如下:51Testing软件测试网qx0`1`8S*w)x;yl

F7z+H"C{8i$y8vW051Testing软件测试网e@Yf8Tu

51Testing软件测试网$bFC'biWU F J$U `

public void onCreate(Bundle savedInstanceState) {
(m s UUOA%b0       super.onCreate(savedInstanceState); 51Testing软件测试网n\:~ O'P V U
       setContentView(R.layout.main); 

O A6sXX1`E0

e j*zD,E0       editText = (EditText) findViewById(R.id.weather_city_edit); 
+[nu"\_GP%[0       Button button = (Button) findViewById(R.id.goQuery); 
a4\^g:l'f#Dl0       button.setOnClickListener(this); 51Testing软件测试网1uUe:wV8CN-cEK
51Testing软件测试网^#Q0M;W x

a-k|'jA}!M e)^"~0public void onClick(View v) { 51Testing软件测试网6n8?+R,RvN
       new GetWeatherTask().execute(“aaa”); 
c y t Pp g0}
51Testing软件测试网 R}O{ X$U@C fA d

51Testing软件测试网]5|3b+YGhJ:}

class GetWeatherTask extends AsyncTask⁢<String, Integer, String> { 51Testing软件测试网|"a~C7ZU{
    protected String doInBackground(String... params) { 51Testing软件测试网%e+t p%oO'B
         return getWetherByCity(params[0]); 51Testing软件测试网 c hAZ*@B ? }
    }
LL|vhSs0    protected void onPostExecute(String result) { 51Testing软件测试网9R!N r"X7u+?&RY
         setTitle(result);
7B@c W w$KbH0    } 
)Po/|:d3e"|-Or"`0}

Nc fwe7x0

TAG:

 

评分:0

我来说两句

Open Toolbar