多线程指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。
线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制。但与进程不同的是,同类的多个线程共享一块内存空间和一组系统资源,所以系统在各个线程之间切换时,资源占用要比进程小得多,正因如此,线程也被称为轻量级进程。一个进程中可以包含多个线程。图所示是计时器程序进程和线程之间的关系,主线程负责管理子线程,即子线程的启动、挂起、停止等操作。
在Android的文档里面之处,Android中是使用的是Java当中标准的线程模型。
在Android中线程分MainThread和WorkerThread,除了MainThread之外的所有线程都称为WorkerThread。
Android启动线程和Java一样有两种方式,一种是直接Thread类的start方法,也就是一般写一个自己的类来继承Thread类。另外一种方式其实和这个差不多,那就是Runnable接口,然后把Runnable的子类对象传递给Thread类再创建Thread对象.总之都是需要创建Thread对象,然后调用Thread类的start方法启动线程。
1,第一种方式是直接继承Thread类:
class MyThread extends Thread {
public void run() {
}
}
在主线程中启动这个线程:
public class Test {
public static void main(String[] args) {
new MyThread().start();// 启动了我们的线程了
}
}
2,第二种方式是实现Runnable接口:
public class MyRunnable implements Runnable{
public void run(){
}
}
在主线程中启动这个线程:
public class Test{
public static void main(String[] args){
Thread t=new Thread(new MyRunnable());//这里比第一种创建线程对象多了个任务对象
t.start();
}
}
区别就是,一个是直接创建Thread对象(代表的是一个线程),另外一个是需要implement了Runnable接口对象作为创建Thread对象的参数。Runnable其实我们称为线程任务(线程体)。
在Android中,所有的UI代码都是运行在MainThread中的。而WorkerThread原则上是不能操作UI的。
举一个建的例子来说明:
开发步骤:
1,新建一个Android应用程序
2,在布局文件中添加一个Button和一个TextView控件标签,并为其设置属性和值
3,在Activity中,声明Button控件变量并根据id获得控件对象 ,设置该Button的监听器
4,在Activity中,创建一个Thread的继承类,并重写run()方法
5,要求点击button时,开始在worker thread中改变TextView控件的值
package com.tangbc.test12;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button button;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new ButtonListener());
}
class ButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
Thread t = new MyThread();
t.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
textView.setText("改变");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
编译时没有错误,但运行是就会报错
但也有特殊的控件是允许的,如ProgressBar
看下面的例子:
开发步骤:
1,新建一个Android应用程序
2,在布局文件中添加一个Button和一个ProgressBar控件标签,并为其设置属性和值
3,在Activity中,声明Button和ProgressBar控件变量并根据id获得控件对象 ,并设置该Button的监听器
4,在Activity中,创建一个Thread的继承类,并重写run()方法 ,实现每十分之一秒,ProgressBar的值加10
5,要求点击button时,开始该线程
package com.tangbc.s02e05_progressthread;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private Button button;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
button.setOnClickListener(new ButtonListener());
}
class ButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
MyThread t = new MyThread();
t.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.setProgress(progressBar.getProgress() + 1);
}
}
}
}
在一个应用程序中,主线程通常用于接收用户的输入,以及将运算的结果反馈给用户,所以说对于一些肯呢过会产生阻塞的操作,必须放置在WorkerThread中。那么这样就会产生一个问题在workerThread中得出的结果无法反馈到UI,又不能将该过程放置在mainThread里,这时候就会产生WorkerThread和mainThread之间的通信,将WorkerThread的运行结果反馈给mainThread。这里就牵涉到了Android中的handler概念