android多线程学习(一)
一、java中的多线程
在Java中有两种方法实现线程:1.继承Thread类、2.实现接口Runnable。
1.继承Thread类
继承Thread类的方式,它继承Thread类并重写其中的run()方法,使用这个方法初始化这个类的实例的时候,target可以为null,表示由this实例来执行线程。
public class test extends Thread{
boolean sign = true;
@Override
public void run(){
while(sign){
System.out.println("Hello,I am testThread");
}
}
public static void main(String[] args){
test t = new test();
t.start();
}
}
2.实现Runnable接口
实现Runnable接口,并重写该接口的run()方法,这个方法就是线程的执行体,但是要将该实现类作为Thread构造参数中的Target来创建线程,这样的Thread对象才是真正的线程对象。
public class CreateThread implements Runnable{
public static void main(String[] args){
Thread t = new Thread(new CreateThread());
t.start();
}
@Override
public void run(){
System.out.println("Oh,I am Runnable");
}
}
以上是大家最为熟知的在java中创建线程的方法,那么在android是否可以以同样的方式来创建线程呢,答案是肯定的,因为android是基于java开发的,所以android能使用以上两种方法来实现多线程。
Android中需要多线程吗?答案也是肯定的。我们都知道,Android应用大多都是需要界面的,当应用启动的时候,系统会创建一个主线程,这个主线程的任务就是负责向各UI组件分发事件,而应用与UI组件的交互也是发生在这个主线程里面的,所以我们创建的Activity、Service等都是运行在主线程的。但在一些特定的耗时的操作上的时候,比如下载、I/O读写、数据库操作等需要很长时间的任务时,如果这些操作都在主线程完成,那么在进行这些操作的时候,用户将不能做任何其他的事情,只能等待,因为这个时候,界面被操作所堵塞,所以这个时候我们就会考虑使用Thread线程来解决问题。
二、Android中的多线程
1.Handler
对于Android平台来说,UI控件都不是线程安全的,所以更新UI只能在主线程中更新,在子线程中更新是很危险的,而Handler就解决了这个问题,Handler运行在主线程中,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的MessageQueue中,Handler会接受从子线程传过来的Message或者Runnable对象,并把这些消息放入主线程的MessageQueue中,配合主线程更新UI控件。
Handler中分发消息有以下方法:
post(Runnable) //允许将一个Runnable对象放到主线程队列中
//把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,立即执行。
postAtTime(Runnable,long)
//把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,在特定的时间执行。
postDelayed(Runnable long)
//把一个Runnable入队到消息队列中,UI线程从消息队列中取出这个对象后,延迟delayMills秒执行
//以下方法大致同上
sendEmptyMessage(int)
sendMessage(Message) //允许你将带数据的message放到主线程队列中
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
sendMessage使用Handler:(1)重写handleMessage()函数并初始化Handler对象
(2)定义Thread并初始化线程对象,然后在Thread的run()方法里操作数据,并通过handler.sendMessage()方法将message传输到handler对象中。
(3)在handleMessage()函数中实现对Message的处理。
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity{
private TextView txt;
private Button btn;
Handler handler = new Handler(){ //在这里进行初始化
public void handleMessage(Message msg){
txt.setText("消息传过来了"+msg.arg1);
}
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView)findViewById(R.id.txtView);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
ThreadTest t1=new ThreadTest(); //新建线程
new Thread(t1).start();
}
});
}
private class ThreadTest implements Runnable{
public void run(){
Log.i(TAG,"子线程运行中");
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
Message msg = new Message();
msg.arg1 = 1;
hander.sendMessage(msg); //在线程的run()方法中sendMessage给handler
}
}
}
post使用Handler:(1)初始化Handler对象
(2)定义Thread并初始化线程对象,然后在Thread的run()方法里使用post方法将另一个Runnable对象(匿名类)传到handler中,并在主线程中执行这个Runnable的run方法,run方法里是操作的数据
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity{
private TextView txt;
private Button btn;
Handler handler = new Handler(); //在这里进行初始化
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView)findViewById(R.id.txtView);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
new Thread(new Runnable(){
@Overrid
public void run() {
// tvMessage.setText("...");
// 以上操作会报错,无法再子线程中访问UI组件,UI组件的属性必须在UI线程中访问
// 使用post方式修改UI组件tvMessage的Text属性
handler.post(new Runnable(){
@Override
public void run() {
txt.setText("发送了一条消息");
}
});
}
}).start();
}
});
}
}
最后,谢谢阅读~~