安卓开发经常要用到多线程,最要了解的是Thread、Handle、HandlerThread的区别。以下内容为转载。
从Android中Thread(java.lang.Thread -> java.lang.Object)描述可以看出,Android的Thread没有对Java的Thread做任何封装,但是Android提供了一个继承自Thread的类HandlerThread(android.os.HandlerThread -> java.lang.Thread),这个类对Java的Thread做了很多便利Android系统的封装。
说到Java的Thread,就不得不说一下Runnable类(java.lang.Runnable),它表示内部代码是可以被执行的,经常与Thread一起使用。
_ueditor_page_break_tag_
Thread最常用的使用方法有2种。一种是创建一个继承于Thread的子类,重载(Override)实现run()方法,之后实例化这个子类对象再调用start()方法;另一种是直接实例构造Thread对象,使用Thread(Runnable)方法,只用重载实现Runnable对象的run()方法,再对Thread对象使用start()方法。代码如下:
方法一:
public class Test { static class MyThread extends Thread { @Override public void run() { // TODO Auto-generated method stub super.run(); // you can do something youself } } // you can call this method anywhere in this class void useYourThread() { new MyThread().start(); } }
方法二:
public class Test { void useYourThread() { // implement Thread object & a anonymous Runnable object new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub // you can do something yourself } }).start(); } }
Android提供的HandlerThread继承自Thread,并且在这个线程里放入了一个Looper(android.os.Looper -> java.lang.Object)对象,也就是说这个Looper对象是在新建线程里运转的。Looper对象可以简单的理解成一个循环处理工具。为了更好的理解HandlerThread,应该先看一下Handler相关的内容。
从Android文档的Handler(android.os.Handler -> java.lang.Object)描述可以看出,Android的Handler和Java的Handler(java.util.logging.Handler -> java.lang.Object)是基本上没有关系的。Android提供的Handler是为了传递消息(android.os.Message)和启动Runnable对象而使用的。
android.os.Handler对象只能在某一个线程中运行并可以使用这个线程的消息队列(Message queue)。从官方API文档可以看到,实例化Handler有4种方法。其中有2种是需要Looper对象参数的,这2种构造方法就可以使Handler运行在包含给定Looper对象的线程中;如果不给定,则运行在当前线程中(一般没有新建线程的情况下,会运行在Android程序主线程中,也就UI线程中)。
android.os.Handler在多线程和IPC(进程间交互)中都起到非常重要的做用。
以下是当前线程中运行的Handler对象的常用方法:
Handler h = new Handler() { public void handleMessage(android.os.Message msg) { // do something to handle the Message }; };
android.os.Handler可以通过Looper对象实例化,并运行于另外的线程中,Android提供了让Handler运行于其它线程的线程实现,也是就HandlerThread。HandlerThread对象start后可以获得其Looper对象,并且使用这个Looper对象实例Handler,这样Handler就是工作于前面实例的HandlerThread(其实质就是线程Thread)里了。HandlerThread使用常用代码如下:
void useHanlerThread() { // two ways to construct HandlerThread HandlerThread hThread = new HandlerThread("AnyName", // a property in android.os.Process Process.THREAD_PRIORITY_BACKGROUND); // HandlerThread hThread2 = new HandlerThread("AnyName"); hThread.start(); // get Looper object of hThread(HandlerThread) Looper looper = hThread.getLooper(); Handler h = new Handler(looper) { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); } }; }
HandlerThread是继承于Thread的,所以在Thread的适用范围内HandlerThread是同样适用的。如果在android.os.Handler里需要执行一些非常耗时的任务,就应该把Handler放到HandlerThread里面执行(或者在Handler里新开线程执行),而不应该直接在UI线程中执行,否则会增加出现ANR(Application Not Responding)的可能。
以上转载:http://www.juwends.com/tech/android/android_thread_handler.html
一个点击事件,获取网页信息:
Button getquote = (Button)findViewById(R.id.button8); getquote.setOnClickListener(new OnClickListener() { public void onClick(View view) { // push soap request into background. new Thread(new Runnable(){ @Override public void run() { // try { // Thread.sleep(10000); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // try { // getPaiMaiInfo(""); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (XmlPullParserException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } try { //String PaiMai=posturl(""); URL url=new URL(""); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(5000); InputStream inStream= connection.getInputStream(); ByteArrayOutputStream data=new ByteArrayOutputStream();//新建一字节数组输出流 byte[] buffer = new byte[1024];//在内存中开辟一段缓冲区,接受网络输入流 int len=0; while((len=inStream.read(buffer))!=-1){ data.write(buffer, 0, len); //缓冲区满了之后将缓冲区的内容写到输出流 } inStream.close(); String tempContent=new String(data.toByteArray(),"utf-8");//最后可以将得到的输出流转成utf-8编码的字符串,便可进一步处理 //保存数据 save(tempContent); Message msg = new Message(); msg.obj = tempContent; result1Handler.sendMessage(msg); // 向Handler发送消息,更新UI } catch(Exception e) { Message msg = new Message(); msg.obj = e.getMessage(); result1Handler.sendMessage(msg); } // Message msg = new Message(); // msg.obj = "123"; // result1Handler.sendMessage(msg); } },"DOINBACKGROUND").start(); } }); private Handler result1Handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); TextView tv1=(TextView)findViewById(R.id.editText1); tv1.setText(msg.obj.toString()); } };