Android 多线程及handler 理解

Android 的多线程是基于Linux本身的多线程机制,而多线程机制之间的同步又是通过java本身的线程同步,线程是运行在同一地址空间的不同调度单元,有自己的堆栈空间,而进程是运行在独立的,彼此之间互不察觉的不同调度单元。
一个应用程序可能包含多个线程,每个线程都有一个run()方法,run()执行完毕后,所有的线程就自动结束。
每个线程都有一个消息队列,用于不同线程之间传递消息。在run()方法内部,如果不主动读取消息队列中的消息,这些消息就是一些不用的消息,因为没被处理。
在android系统中,读取消息和处理消息是两个步骤,并有不同的部分完成,先读取消息,然后才处理消息,但是,无论是本线程还是其他线程,都不能直接处理消息队列中的消息,需要通过线程内部定义一个Handler类对象来处理消息队列,一个Thread只能有一个Handler对象,在实际应用中,读取消息队列一般需要循环执行,即不断的从消息队列中获取消息并进行相应的处理,这就需要一个Looper对象。
Looper对象用于循环读取消息队列的值,并回调Handler对象中定义的消息处理函数,同时,Looper对象还可以将读出的消息从队列中移除,执行完一次消息处理后,在循环从消息队列中读取下一个消息,知道Looper对象调用stop方法退出循环,若没有消息,Looper对象则会等待,线程不会退出。
为了方便使用Looper功能,android又定义了一个HandlerThread类,该类基于Thread,并且内部已经添加了Looper功能,只需复写其onLooperPrepared()方法,android中,一个Activity就是一个线程,多个Activity之间的切换是在同一个线程中。
1.2.1Thread
Thread 是一个类,和java中的基本相同,但是抛弃了一些java线程不安全的做法,比如,终止一个thread,在java中,可以使用thread。Stop等,但在android中,这些方法没有实现,不能直接使用。
新建一个thread需要两个函数:
1、构造函数
在android中,新建的线程多为activity,service等程序片段服务,而在线程的内部执行过程中,很多时候都需要使用应用程序内部的context对象,因此,构造函数中往往会传递应用程序的context对象,从而在线程的内部可以调用context相关的系统服务。
2、Run()函数
该函数是thread中必须使用的对象,用于完成具体的任务。启动线程时,不能直接调用thread.run()方法,而是调用thread.start()方法启动,start()方法是thread内部使用的,该方法包括初始化线程的工作,然后回调run()方法,这些对应用程序是不可见的。
Run()方法执行完后就自动停止线程,因此,如果需要线程循环执行run方法,可以在run内部定义一个状态变量,通过检查该变量,决定是否执行,同时可在线程外设置该状态变量的值,从而终止该线程。
package com.java.lyn;

import java.io.IOException;

import android.graphics.Canvas;
import android.view.SurfaceHolder;
import static com.java.lyn.Constant.*;
public class MenuThread extends Thread{
MenuView mv;
SurfaceHolder holder;//显示一个surface的抽象接口,可以控制surface的大小和格式,
//以及在surface上编辑像素,和监视surace的改变。这个接口通//常通过SurfaceView类实现。
public MenuThread(MenuView mv)//构造器
{
this.mv = mv;
this.holder =mv.getHolder();
}
public void run()//run()方法
{
Canvas canvas;
while(MENU_FLAG)
{
canvas = null;
if(true)
{
try
{
canvas=this.holder.lockCanvas();//得到一个canvas实例
synchronized(this.holder)
{
mv.onDraw(canvas);
}
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(canvas!=null)
{
this.holder.unlockCanvasAndPost(canvas); // 将画好的画布提交
}

	      }
	   }
		try
		{
			sleep(2000);
		}catch(Exception e)
	      {
	    	  e.printStackTrace();
	      }
     }
}

}
1.2.2Runnable
作用和thread相同,只是这是一个接口,待看。。。。。。。。

1.3消息发送handler
Handler用于处理线程中的消息队列,当looper从消息队列中获取消息后,会把消息派发给handler对象。一个线程一个handler对象,所以,只要拥有其他线程的handler对象的引用,就可以像其发送消息,还可以给本线程发送消息。
一般有两种用途:
1、实现一个定时任务。
2、在线程间传递数据。
对于1.需要首先了解下message的结构,他是一个数据结构类,包含很多成员变量和方法,对于简单的消息处理,一般需要了解3项,分别是:
In what:用于区分消息类型
Int arg1:额外的消息参数
Int arg2:额外的消息参数;
(1)handler发送消息方式
两种:一类是postXXX()方法,
一类是sendXXX方法,该方法发送一个message类型的消息到消息队列,当消息被处理时,系统会调用handler对象定义的handlermessage方法处理该消息,实现定时任务时主要用到sendXXX()方法:
1、sendEmptyMessage(int)空消息是指仅仅包含what值。
case MotionEvent.ACTION_UP:
if(x>=0&&x<=105&&y>=300&&y<=335)
{
activity.hd.sendEmptyMessage(GAME_LOAD);
}
else if(x>=0&&x<=105&&y>=340&&y<=375)
{
activity.hd.sendEmptyMessage(GAME_HELP);
}
else if(x>=0&&x<=105&&y>=380&&y<=415)
{
activity.hd.sendEmptyMessage(GAME_ABOUT);
}
else if(x>=0&&x<=105&&y>=420&&y<=455)
{
System.exit(0);
}
Exp2:
hd=new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);//////
switch(msg.what)
{
case GAME_SOUND:
sv=new SoundView(PuzzlesgameActivity.this);
setContentView(sv);
break;
case GAME_MENU:
MENU_FLAG=true;//设置MenuThread标志位为true
mv=new MenuView(PuzzlesgameActivity.this);
setContentView(mv);
break;
case GAME_LOAD:
MENU_FLAG=false;//设置MenuThread标志位为false
setContentView(R.layout.icon);
new Thread()
{
public void run()
{
try
{
sleep(2000);
}catch(Exception e)
{
e.printStackTrace();
}
hd.sendEmptyMessage(GAME_PLAY);
}

    	        }.start();
    	        break;

};//分号
(2)同步实现进程:
Synchornized(){
If()
Tyr{
…………………
}catch()
{
}finially{}
例如:
public void run()
{
Canvas canvas;
while(MENU_FLAG)
{
canvas = null;
if(true)
{
try
{
canvas=this.holder.lockCanvas();//得到一个canvas实例
synchronized(this.holder)
{
mv.onDraw(canvas);
}
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(canvas!=null)
{
this.holder.unlockCanvasAndPost(canvas); // 将画好的画布提交
}

	      }
	   }
		try
		{
			sleep(2000);
		}catch(Exception e)
	      {
	    	  e.printStackTrace();
	      }
     }
}
发布了133 篇原创文章 · 获赞 2 · 访问量 3369

猜你喜欢

转载自blog.csdn.net/qq_42894864/article/details/104730463
今日推荐