Handler + Looper + Message Queue - 안 드 로 이 드 비동기 처리 에 대한 각 소의 이해 + 나의 개인 적 인 생각

45571 단어 messagequeue
1. 몇 가지 관건 적 인 개념 1. Message Queue: 일종 의 데이터 구조 로 이름 이 알려 진 것 을 보면 메시지 대기 열 이 고 메 시 지 를 저장 하 는 곳 입 니 다.모든 스 레 드 는 하나의 Message Queue 데이터 구조 만 가 질 수 있 습 니 다.스 레 드 를 만 들 때 Message Queue 를 자동 으로 만 들 지 않 습 니 다.보통 Looper 대상 을 사용 하여 이 스 레 드 의 Message Queue 를 관리 합 니 다.메 인 스 레 드 를 만 들 때 기본 Looper 대상 을 만 들 고 Looper 대상 을 만 들 면 Message Queue 가 자동 으로 생 성 됩 니 다.다른 비 주 스 레 드 는 Looper 를 자동 으로 만 들 지 않 습 니 다. 필요 할 때 prepare 함 수 를 호출 하여 이 루어 집 니 다.
1 final MessageQueue mQueue;

2 private Looper() {

3         mQueue = new MessageQueue();

4         mRun = true;

5         mThread = Thread.currentThread();

6     }

다음은 prepare 방법, 정적 방법.
1 private static final ThreadLocal sThreadLocal = new ThreadLocal();

2 public static final void prepare() {

3         if (sThreadLocal.get() != null) {

4             throw new RuntimeException("Only one Looper may be created per thread");

5         }

6         sThreadLocal.set(new Looper());

7 }

2. Message: 메시지 대상, Message Queue 에 저 장 된 대상.하나의 Message Queue 에 여러 개의 Message 가 포함 되 어 있 습 니 다.Message 인 스 턴 스 대상 의 획득,
보통 Message 클래스 의 정적 방법 obtain () 을 사용 합 니 다.
이 방법 은 여러 개의 리 셋 버 전 을 선택 할 수 있 습 니 다.이 생 성 은 반드시 새로운 인 스 턴 스 를 직접 만 드 는 것 이 아니 라 Message Pool (메시지 풀) 에서 사용 가능 한 Message 인 스 턴 스 가 있 는 지 확인 하고 존재 하면 이 인 스 턴 스 를 직접 꺼 냅 니 다.Message Pool 에 사용 가능 한 Message 인 스 턴 스 가 없 으 면 주어진 매개 변수 로 Message 대상 을 만 듭 니 다.removeMessages () 를 호출 할 때 Message 를 Message Queue 에서 삭제 하고 Message Pool 에 넣 습 니 다.위 와 같은 방식 을 제외 하고 Handler 대상 의 obtainMessage () 를 통 해 Message 인 스 턴 스 를 얻 을 수 있 습 니 다.
3. Looper: Message Queue 의 관리자 입 니 다.모든 Message Queue 는 Looper 에서 벗 어 나 존재 할 수 없습니다 (방금 언급 한 바 와 같이 하나의 Looper 가 하나의 message 대상 에 대한 관리). Looper 대상 의 생 성 은 prepare 함 수 를 통 해 이 루어 집 니 다.동시에 모든 Looper 대상 은 하나의 스 레 드 와 연 결 됩 니 다.Looper. my Looper () 를 호출 하면 현재 스 레 드 의 Looper 대상 이 Looper 대상 을 만 들 때 Message Queue 대상 을 동시에 만 들 수 있 습 니 다.메 인 스 레 드 에 기본 Looper 가 있 는 것 을 제외 하고 다른 스 레 드 는 기본적으로 Message Queue 대상 이 없 기 때문에 Message 를 받 아들 일 수 없습니다.받 아들 일 필요 가 있 으 면 Looper 대상 (prepare 함 수 를 통 해) 을 정의 하면 이 스 레 드 는 자신의 Looper 대상 과 Message Queue 데이터 구 조 를 가지 게 됩 니 다.Looper 는 Message Queue 에서 Message 를 꺼 낸 다음 Handler 의 handleMessage 에 맡 깁 니 다.처리 가 완료 되면 Message. recycle () 을 호출 하여 Message Pool 에 넣 습 니 다.
4. Handler: 메시지 의 처리 자, handler 는 전달 해 야 할 정 보 를 Message 로 밀봉 하고 handler 대상 의 obtainMessage () 를 호출 하여 실현 한다.Looper 에 메 시 지 를 전달 하 는 것 은 handler 대상 의 sendmessage () 를 통 해 이 루어 집 니 다.이 어 Looper 가 Message 를 Message Queue 에 넣 었 다.Looper 대상 이 Message Queue 에 Message 가 들 어 있 는 것 을 보고 방송 합 니 다.이 handler 대상 이 이 메 시 지 를 받 은 후 해당 handler 대상 의 handleMessage () 방법 을 호출 합 니 다.
  1   2 

  3 1、        Message

  4 

  5 package test.message;

  6 

  7 import android.app.Activity;

  8 import android.os.Bundle;

  9 import android.os.Handler;

 10 import android.os.Looper;

 11 import android.os.Message;

 12 import android.view.View;

 13 import android.widget.Button;

 14 import android.widget.TextView;

 15 

 16 public class MainActivity extends Activity {

 17     

 18     private Button btnTest;

 19     private TextView textView;

 20     

 21     private Handler handler;

 22     

 23     @Override

 24     public void onCreate(Bundle savedInstanceState) {

 25         super.onCreate(savedInstanceState);

 26         setContentView(R.layout.main);

 27         

 28         btnTest = (Button)this.findViewById(R.id.btn_01);

 29         textView = (TextView)this.findViewById(R.id.view_01);

 30         

 31         btnTest.setOnClickListener(new View.OnClickListener() {

 32             

 33             @Override

 34             public void onClick(View arg0) {

 35                 

 36                 Looper looper = Looper.getMainLooper(); //    Looper  

 37                 //       Looper     handler,

 38                 //  ,  handler   Message         MessageQueue。

 39                 handler = new MyHandler(looper);

 40                 handler.removeMessages(0);

 41                 //  Message  

 42                 //     :      message  ,   handler      

 43                 //            

 44                 //            

 45                 Message msg = handler.obtainMessage(1,1,1,"       ");

 46                 

 47                 handler.sendMessage(msg); //    

 48                 

 49             }

 50         });

 51     }

 52     

 53     class MyHandler extends Handler{

 54         

 55         public MyHandler(Looper looper){

 56             super(looper);

 57         }

 58         

 59         public void handleMessage(Message msg){

 60             super.handleMessage(msg);

 61             textView.setText("      Handler,     :"+(String)msg.obj);

 62         }

 63     }

 64 }

 65 

 66 2、          Message

 67 

 68 package test.message;

 69 

 70 import android.app.Activity;

 71 import android.os.Bundle;

 72 import android.os.Handler;

 73 import android.os.Looper;

 74 import android.os.Message;

 75 import android.view.View;

 76 import android.widget.Button;

 77 import android.widget.TextView;

 78 

 79 public class MainActivity extends Activity {

 80     

 81     private Button btnTest;

 82     private TextView textView;

 83     

 84     private Handler handler;

 85     

 86     @Override

 87     public void onCreate(Bundle savedInstanceState) {

 88         super.onCreate(savedInstanceState);

 89         setContentView(R.layout.main);

 90         

 91         btnTest = (Button)this.findViewById(R.id.btn_01);

 92         textView = (TextView)this.findViewById(R.id.view_01);

 93         

 94         btnTest.setOnClickListener(new View.OnClickListener() {

 95             

 96             @Override

 97             public void onClick(View arg0) {

 98                 

 99                 //                           

100                 //                     ,   ?  

101                 new MyThread().start();    

102             }

103         });

104     }

105     

106     class MyHandler extends Handler{

107         

108         public MyHandler(Looper looper){

109             super(looper);

110         }

111         

112         public void handleMessage(Message msg){

113             super.handleMessage(msg);

114             textView.setText("      Handler,     :"+(String)msg.obj);

115         }

116     }

117     

118     //       

119     class MyThread extends Thread{

120         

121         public void run(){

122             Looper looper = Looper.getMainLooper(); //    Looper  

123             //       Looper     handler,

124             //  ,  handler   Message         MessageQueue。

125             handler = new MyHandler(looper);

126 

127             //  Message  

128             //     :      message  ,   handler      

129             //            

130             //            

131             Message msg = handler.obtainMessage(1,1,1,"        ");

132             

133             handler.sendMessage(msg); //                

134         }

135     }

136 }

137 

138 3、          Message

139 

140 package test.message;

141 

142 import android.app.Activity;

143 import android.os.Bundle;

144 import android.os.Handler;

145 import android.os.Looper;

146 import android.os.Message;

147 import android.view.View;

148 import android.widget.Button;

149 import android.widget.TextView;

150 

151 public class MainActivity extends Activity {

152     

153     private Button btnTest;

154     private TextView textView;

155     

156     private Handler handler;

157     

158     @Override

159     public void onCreate(Bundle savedInstanceState) {

160         super.onCreate(savedInstanceState);

161         setContentView(R.layout.main);

162         

163         btnTest = (Button)this.findViewById(R.id.btn_01);

164         textView = (TextView)this.findViewById(R.id.view_01);

165         

166         

167         //    

168         new MyThread().start();    

169         

170         btnTest.setOnClickListener(new View.OnClickListener() {

171             

172             @Override

173             public void onClick(View arg0) {

174                 //  handler        

175                 //              

176                 Message msg = handler.obtainMessage(1,1,1,"        ");

177                 handler.sendMessage(msg);

178             }

179         });

180     }

181     

182     class MyHandler extends Handler{

183         

184         public MyHandler(Looper looper){

185             super(looper);

186         }

187         

188         public void handleMessage(Message msg){

189             super.handleMessage(msg);

190             textView.setText("      Handler,     :"+(String)msg.obj);

191         }

192     }

193     

194     class MyThread extends Thread{

195         

196         public void run(){

197             Looper.prepare(); //      Looper  ,      

198             

199             //   :   handler          ,  ,

200             //         handler  ,     ,          ?

201             //      ???  ,          ,      Looper  

202             //203             //  Looper.myLooper()         Looper   

204             handler = new ThreadHandler(Looper.myLooper());

205             

206             //    ,    ?

207             //        ,   MessageQueue    。

208             //      ,           ???

209             Looper.loop(); 

210 

211         }

212         

213         //            

214         class ThreadHandler extends Handler{

215             

216             public ThreadHandler(Looper looper){

217                 super(looper);

218             }

219             

220             public void handleMessage(Message msg){

221                 //        MessageQueue  Message    

222                 //               

223                 handler = new MyHandler(Looper.getMainLooper());

224                 

225                 Message msg2 = handler.obtainMessage(1,1,1,"     :"+(String)msg.obj);

226                 

227                 handler.sendMessage(msg2);

228             }

229         }

230     }

231 }

232 

233 4、         Message 

234 

235 package test.message;

236 

237 import android.app.Activity;

238 import android.os.Bundle;

239 import android.os.Handler;

240 import android.os.Looper;

241 import android.os.Message;

242 import android.view.View;

243 import android.widget.Button;

244 import android.widget.TextView;

245 

246 public class MainActivity extends Activity {

247     

248     private Button btnTest;

249     private TextView textView;

250     

251     private Handler handler;

252     

253     @Override

254     public void onCreate(Bundle savedInstanceState) {

255         super.onCreate(savedInstanceState);

256         setContentView(R.layout.main);

257         

258         btnTest = (Button)this.findViewById(R.id.btn_01);

259         textView = (TextView)this.findViewById(R.id.view_01);

260         

261         

262         btnTest.setOnClickListener(new View.OnClickListener() {

263             

264             @Override

265             public void onClick(View arg0) {

266                 //    

267                 new MyThread().start();    

268             }

269         });

270     }

271     

272     class MyHandler extends Handler{

273         

274         public MyHandler(Looper looper){

275             super(looper);

276         }

277         

278         public void handleMessage(Message msg){

279             super.handleMessage(msg);

280             textView.setText((String)msg.obj);

281         }

282     }    

283     

284     class MyThread extends Thread{

285         

286         public void run(){

287             Looper.prepare(); //      Looper  

288             //  Looper.myLooper()         Looper   

289             handler = new ThreadHandler(Looper.myLooper());

290             Message msg = handler.obtainMessage(1,1,1,"   ");

291             handler.sendMessage(msg);

292             

293             Looper.loop(); 

294 

295         }

296         

297         //            

298         class ThreadHandler extends Handler{

299             

300             public ThreadHandler(Looper looper){

301                 super(looper);

302             }

303             

304             public void handleMessage(Message msg){

305                 //        MessageQueue  Message    

306                 //               

307                 //                  

308                 if(msg.what == 1 && msg.obj.equals("   ")){

309                     

310                     handler = new MyHandler(Looper.getMainLooper());

311                     

312                     Message msg2 = handler.obtainMessage(1,1,1,"     :           Message");

313                     

314                     handler.sendMessage(msg2);                

315                 }

316 

317             }

318         }

319     }

320 }

321 

322 323                  main.xml

324 

325 <?xml version="1.0" encoding="utf-8"?>

326 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

327     android:rientation="vertical"

328     android:layout_width="fill_parent"

329     android:layout_height="fill_parent"

330     >

331 <TextView  android:id="@+id/view_01"

332     android:layout_width="fill_parent" 

333     android:layout_height="wrap_content" 

334     android:text="@string/hello"

335     />

336     

337 <Button android:id="@+id/btn_01" 

338     android:layout_width="fill_parent" 

339     android:layout_height="wrap_content" 

340     android:text="    " />

341 </LinearLayout>

==================================================================================================
링크 몇 개 제공
http://blog.csdn.net/mylzc/article/details/6771331
http://tanghaibo001.blog.163.com/blog/static/9068612020111287218197/
http://www.cnblogs.com/angeldevil/p/3340644.html
http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html
http://www.cnblogs.com/angeldevil/p/3340644.html
 
/ / 개인 적 인 이해:
위의 네 그룹 코드 의 예 참조 (final 중의 1 - 321 줄) 
하나의 스 레 드 에 하나의 Looper 가 message Queue 메 인 스 레 드 를 관리 합 니 다 (ui 스 레 드 의 Looper 와 messagequue 가 자동 으로 다른 스 레 드 를 만 들 려 면 정적 인 방법 prepare (Looper) 가 필요 합 니 다. Looper 생 성 message Queue 도 생 성,)
message Queue 저장 메시지
비동기 처 리 는 실제 적 으로 서로 다른 스 레 드 handler 에 대한 작업 이 고 handler 는 생 성 된 message 를 자신의 messagequue 에 보 내 는 것 을 책임 집 니 다. Looper 는 "queue 에 새로운 소식 이 있 는 지 자주 보고 있 으 면 소식 을 얻 습 니 다" 라 고 책임 집 니 다.
< 코드 이해 이해 이해 이렇게 이해 하 는 게 맞 는 지 보고 있어 요 >
 
/ / 최종 버 전 
메 시 지 를 보 내 는 < 또는 messagequue 에 대한 조작 > 은 모두 특정한 Looper 의 handler 에 속 하 는 것 입 니 다. 비동기 처리 실현 의 관건 은 다른 스 레 드 가 handler 에 대한 호출 입 니 다. 엄 밀 히 말 하면 보 낸 호출 입 니 다.
스 레 드 A 가 스 레 드 B 에 게 메 시 지 를 보 냅 니 다:
스 레 드 A 호출 스 레 드 B 의 handler obtain message
그리고 sendmessage
이 때 온라인 정 B 의 messagequue 에 새로운 message 가 나 타 났 습 니 다.
Looper 의 감청 을 통 해 새로운 message 를 발견 한 후 이 message 에 해당 하 는 조작 을 합 니 다.
이렇게 해서 비동기 처리 가 완성 되 었 다.

좋은 웹페이지 즐겨찾기