导航:首页 > 操作系统 > 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使用相关的资料

热点内容
小寻app是做什么的 浏览:647
c语言中编译和运行 浏览:999
画流图找循环编译原理 浏览:137
oppo手机西瓜视频的文件夹 浏览:867
骑手一般用哪个app 浏览:610
程序员老板用什么手机 浏览:848
比心app头像不通过为什么 浏览:105
加密币市值前十走势 浏览:190
单片机学习推荐课程 浏览:473
对数ln的运算法则图片 浏览:735
仿微博app源码 浏览:781
怎么取消调用app 浏览:545
程序员去哪里求助 浏览:834
服务器里的端口是什么 浏览:975
aspnetjavaphp 浏览:399
程序员毕业时间 浏览:286
程序员用户免费软件 浏览:754
51单片机汇编语言指令 浏览:139
女程序员好难 浏览:688
三田压缩机与电装 浏览:710