導航:首頁 > 操作系統 > androidlooper使用

androidlooper使用

發布時間:2022-07-29 21:09:59

android在子線程用handler發送的消息,主線程是怎麼loop到的

因為你是在主線程創建的handler實例,比如你是這樣實例化handler

然後調用looper.loop();就開始了消息循環。這就是為什麼在主線程發消息住線程還能收到消息的原因。因為發送消息的實例是在主線程實例化的就有了主線程的looper。

❷ android looper 怎麼理解

Android

Looper

handler
的聯系及處理

最近一直在看
Android
內核的代碼。把
Looper

Handler
這一節先分享一下:

Handle
主要起一個代理中介的作用,具體對象要向底層發請求,得通過
Handler

Handler
把這個請求放進對應的
MessageQueue
(消息隊列)中,而
MessageQueue
是由
Looper
來維護的。
Looper
中有一個循環,循環讀取
MessageQueue
中的請求,發給相應的底層處理(這個過程有點復雜)。當底層
有信息返回時,
也會先放進
MessageQueue
中,
然後對應的
Looper
遍歷,
交給對
應的
Handler
處理。
Handler
找出對應的回調函數或其他已注冊的相關方法,讓
其進行處理,最終在界面有一個反應。

以下是我寫的一個
demo

主要是如何關聯
Looper

Handler

以及對應的線程

MessageQueue

Looper
的一個成員)。

1.
測試方法入口:
testLooper1.java
package com.linquan.test.loop1;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class testLooper1 extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(MyConstant.TAG, "main start...");
new MyThread().start();
Message msg = new Message();
msg.what = MyConstant.CONSTANT3;
while(MyThread.h == null){
Log.d(MyConstant.TAG, "handler is not init ! please wait a
monment....");
try {
Thread.sleep(300);//
由於這里是測試,
所以加上此行代碼,
避免出錯。

際中多為用戶觸發事件,此時
handle
應該已經初始化了。

} catch (InterruptedException e) {
e.printStackTrace();

❸ looper的作用 android 為什麼要循環

給你舉個例子:

用handler傳遞消息時候。你先sendmessage。這時候消息到looper然後你再looper當中更具msg.what獲取相應的消息。looper相當於一個消息收取中介。所以要有循環。我自己的理解。

❹ android的looper類 Looper中有許多都是靜態方法或者靜態屬性,一個應用程序

你好 ,n個應用的話對應 >=n 個進程,一個應用可以有多個進程。
一個線程對應一個looper,ui主線程系默認有一個,非主線程可以調用prepare方法獲得一個looper

❺ android中looper的實現原理,為什麼調用looper.prepare就在當前線程關聯了一個lo

實際上:消息發送和計劃任務提交之後,它們都會進入某線程的消息隊列中,我們可以把這個線程稱之為目標線程。不論是主線程還是子線程都可以成為目標線程。上例中之所以在主線程中處理消息,是因為我們要更新UI,按照android中的規定我們必須由主線程更新UI。所以我們讓主線程成為了目標線程。

那麼如何控制讓某個線程成為目標線程呢?

這就引出了Looper的概念。Android系統中實現了消息循環機制,Android的消息循環是針對線程的,每個線程都可以有自己的消息隊列和消息循環。Android系統中的通過Looper幫助線程維護著一個消息隊列和消息循環。通過Looper.myLooper()得到當前線程的Looper對象,通過Looper.getMainLooper()得到當前進程的主線程的Looper對象。
前面提到每個線程都可以有自己的消息隊列和消息循環,然而我們自己創建的線程默認是沒有消息隊列和消息循環的(及Looper),要想讓一個線程具有消息處理機制我們應該在線程中先調用Looper.prepare()來創建一個Looper對象,然後調用Looper.loop()進入消息循環。如上面的源碼所示。
當我們用Handler的構造方法創建Handler對象時,指定handler對象與哪個具有消息處理機制的線程(具有Looper的線程)相關聯,這個線程就成了目標線程,可以接受消息和計劃任務了。Handler中的構造方法如下:

[java] view
plainprint?

public Handler() {

if (FIND_POTENTIAL_LEAKS) {

final Class<? extends Handler> klass = getClass();

if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&

(klass.getModifiers() & Modifier.STATIC) == 0) {

Log.w(TAG, "The following Handler class should be static or leaks might occur: " +

klass.getCanonicalName());

}

}

mLooper = Looper.myLooper();

if (mLooper == null) {

throw new RuntimeException(

"Can't create handler inside thread that has not called Looper.prepare()");

}

mQueue = mLooper.mQueue;

mCallback = null;

}

public Handler(Looper looper) {

mLooper = looper;

mQueue = looper.mQueue;

mCallback = null;

}
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}

mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}

public Handler(Looper looper) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = null;
}

在上述的計時器的例子中,之所以可以在主線程中處理消息而我們自己並沒有調用Looper.prepare()等方法,是因為Android系統在Activity啟動時為其創建一個消息隊列和消息循環,當我們用無參的Handler構造方法創建對象時又用了當前線程的Looper對象,及將handler與主線程中的Looper對象進行了關聯。

android中是使用Looper機制來完成消息循環的,但每次創建線程時都先初始化Looper比較麻煩,因此Android為我們提供了一個HandlerThread類,他封裝了Looper對象,是我們不用關心Looper的開啟和釋放問題。

不管是主線程還是其他線程只要有Looper的線程,別的線程就可以向這個線程的消息隊列中發送消息和任務。

我們使用HandlerThread類代替上一篇文章中的子線程,並用HandlerThread類中的Looper對象構造Handler,則接受消息的目標線程就不是主線程了,而是HandlerThread線程。代碼如下:

[java] view
plainprint?

public class clockActivity extends Activity {

/** Called when the activity is first created. */

private String TAG="clockActivity";

private Button endButton;

private TextView textView;

private int timer=0;

private boolean isRunning=true;

private Handler handler;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

endButton=(Button)findViewById(R.id.endBtn);

textView=(TextView)findViewById(R.id.textview);

endButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

isRunning=false;

}

});

HandlerThread thread=new HandlerThread("myThread");

handler=new Handler(thread.getLooper());//與HandlerThread中的Looper對象關聯

thread.start();

Runnable r=new Runnable(){

@Override

public void run() {

// TODO Auto-generated method stub

if(isRunning){

textView.setText("走了"+timer+"秒");

timer++;

handler.postDelayed(this, 1000);//提交任務r,延時1秒執行

}

}

};

handler.postDelayed(r, 1000);

}

}
public class clockActivity extends Activity {
/** Called when the activity is first created. */
private String TAG="clockActivity";
private Button endButton;
private TextView textView;
private int timer=0;
private boolean isRunning=true;
private Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
endButton=(Button)findViewById(R.id.endBtn);
textView=(TextView)findViewById(R.id.textview);
endButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
isRunning=false;
}
});
HandlerThread thread=new HandlerThread("myThread");
handler=new Handler(thread.getLooper());//與HandlerThread中的Looper對象關聯
thread.start();
Runnable r=new Runnable(){

@Override
public void run() {
// TODO Auto-generated method stub
if(isRunning){
textView.setText("走了"+timer+"秒");
timer++;
handler.postDelayed(this, 1000);//提交任務r,延時1秒執行
}
}
};
handler.postDelayed(r, 1000);
}
}

此時處理任務會在handlerThread線程中完成。當然這個例子會出線異常:依然是因為在非主線程中更新了UI。這樣做只是為了大家能夠理解這種機制。

深入理解Android消息處理機制對於應用程序開發非常重要,也可以讓我們對線程同步有更加深刻的認識,希望這篇文章可以對朋友們有所幫助。

❻ Android Looper 主線程的Looper.looper()是在哪調用的

http://blog.csdn.net/hello_12413/article/details/51759787
這個可以參考下,

閱讀全文

與androidlooper使用相關的資料

熱點內容
鎖屏密碼加密手機怎麼解除 瀏覽:191
linuxlostfound 瀏覽:132
征途伺服器ip地址 瀏覽:328
git提交代碼命令行 瀏覽:163
什麼叫瀏覽器伺服器結構 瀏覽:155
於謙聊天哪個app 瀏覽:447
小鵬汽車nlp演算法工程師薪資 瀏覽:879
代碼加密與隱藏 瀏覽:647
fordfulkerson演算法 瀏覽:350
京東熱app在哪裡可以下載 瀏覽:874
彩報圖書app哪個好 瀏覽:301
新君威20壓縮比 瀏覽:186
手機php整站 瀏覽:915
windows路由跳轉命令 瀏覽:472
量子遺傳演算法程序 瀏覽:222
各編程語言自帶軟體庫 瀏覽:184
編程最少學習多少 瀏覽:403
禪海蠡測語譯pdf 瀏覽:189
伺服器如何設置主城領地 瀏覽:122
android後台發送簡訊 瀏覽:5