android线程之多线程
2016-04-17 12:35
651 查看
相信大家对于什么是android进程和线程的理论应该都有所了解了,不清楚的可以查看这篇文章
android进程和线程
下面进一步学习,如何实现线程和多线程
什么是单线程,什么是多线程?先看这张图
多线程:它是一组指令的集合,在控制流程语句当中,每一个线程就是一条控制语句,线程与线程之间是可以实现数据共享的,所谓多线程,在某一个时间片段同时有多个任务在一起执行。
线程运行过程中的生命周期
这里不细讲过程
下面才是重点,线程实现的方法,我们先看看java里的线程
java实现线程有两种方式:
■继承Thread类
步骤如下:
1、定义一个普通类去继承Thread类,则表明此类是一个线程类。
语法结构:
2、重写父类中的run方法
语法结构:
3、使用线程
调用start方法来执行线程
语法结构:
线程对象名.start();
■实现Runnable接口
步骤如下
1、定义普通类去实现Runnable接口
语法结构:
2、重写run方法
3、启动线程
-定义自己的线程对象
-定义系统的线程对象,把自己的线程对象作为参数传递到系统的线程对象
-调用start方法执行:thread.start()
当然这两个方式是有区别和优缺点的
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
我们再来看看android的线程
Android和Java一样,它支持使用Java里面的Thread类来进行一步任务处理。所以可以轻松地像上面Java的例子一样来使用Android上的线程,
但是在
android进程和线程
文章里说过
Android UI工具包不是线程安全的。所以,你不能从一个工作线程中操作你的用户界面,你必须从用户界面中对用户界面做所有的操作。因此,有简单的规则,以Android的单线程模型:
•不要阻塞用户界面线程
•不访问用户界面线程以外的安卓用户界面工具包
所以android的线程实现方式跟java一样有两种,但是处理方法有区别
下面我们来看看
说到线程不得说Handler,它是线程间通信的桥梁,Handler的细节在这里
android的消息处理机制
我们直接上程序
Handler消息处理机制
或者可以这样写
然后 通过new得到一个对象实例
向消息队列发送消息可以使用下列方法发送
然后开始创建线程
方式一:继承Thread类
步骤和java创建差不多,直接上程序
开启线程的方法
注意:不一定run()方法里的message都是用上面的方法创建,看情况而定
方式二:实现Runnable接口
直接上程序
注意:有时根据需要可以通过写构造函数传入参数
启动线程方法
有时候为了看起来紧凑可以这样写
Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:
Runnable是一个接口,不是一个线程,一般线程会实现Runnable。 所以如果我们使用匿名内部类是运行在UI主线程的,如果我们使用实现这个Runnable接口的线程类,则是运行在对应线程的。
这种情况下,由于不是在新的线程中使用,所以千万别做复杂的计算逻辑。
下面给出简单例子(经典的在UI中实现计时操作)
XML布局
主程序
先做个简单的描述:
在这个例子里使用了上面的两种方式来创建线程,一个线程实现计时,一线程往TextView写入信息,Button按键按下计时停止
效果图:
点击Button
其实android实现多线程的方法可采用runOnUiThread,post,handle,AsyncTask技术实现。
这里讲解的是使用handler,其他的由大家来。
android进程和线程
下面进一步学习,如何实现线程和多线程
什么是单线程,什么是多线程?先看这张图
多线程:它是一组指令的集合,在控制流程语句当中,每一个线程就是一条控制语句,线程与线程之间是可以实现数据共享的,所谓多线程,在某一个时间片段同时有多个任务在一起执行。
线程运行过程中的生命周期
这里不细讲过程
下面才是重点,线程实现的方法,我们先看看java里的线程
java实现线程有两种方式:
■继承Thread类
步骤如下:
1、定义一个普通类去继承Thread类,则表明此类是一个线程类。
语法结构:
public class 类名 extends Thread{}
2、重写父类中的run方法
语法结构:
public void run() { //线程的执行体 }
3、使用线程
调用start方法来执行线程
语法结构:
线程对象名.start();
■实现Runnable接口
步骤如下
1、定义普通类去实现Runnable接口
语法结构:
public class 类名 implements Runnable{}
2、重写run方法
3、启动线程
-定义自己的线程对象
MyThread myThread = new MyThread();
-定义系统的线程对象,把自己的线程对象作为参数传递到系统的线程对象
Thread thread = new Thread(myThread);
-调用start方法执行:thread.start()
当然这两个方式是有区别和优缺点的
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
我们再来看看android的线程
Android和Java一样,它支持使用Java里面的Thread类来进行一步任务处理。所以可以轻松地像上面Java的例子一样来使用Android上的线程,
但是在
android进程和线程
文章里说过
Android UI工具包不是线程安全的。所以,你不能从一个工作线程中操作你的用户界面,你必须从用户界面中对用户界面做所有的操作。因此,有简单的规则,以Android的单线程模型:
•不要阻塞用户界面线程
•不访问用户界面线程以外的安卓用户界面工具包
所以android的线程实现方式跟java一样有两种,但是处理方法有区别
下面我们来看看
说到线程不得说Handler,它是线程间通信的桥梁,Handler的细节在这里
android的消息处理机制
我们直接上程序
Handler消息处理机制
public class MyHandler extends Handler{ public void handleMessage(Message msg){ switch(msg.what){ case 1 : //处理消息,例如更新UI break; case 2 : //处理消息 break; default : break; } } }
或者可以这样写
Handler mHandler = new Handler(){ public void handleMessage(Message msg){ switch(msg.what){ case 1 : //处理消息,例如更新UI break; case 2 : //处理消息 break; default : break; } } }
然后 通过new得到一个对象实例
MyHandler mHandler = new MyHandler();
向消息队列发送消息可以使用下列方法发送
mHandler.sendMessage(message); mHandler.postDelayed(Runnable r, long delayMillis); mHandler.sendEmptyMessage(int what); mHandler.sendMessage(Message msg); mHandler.sendEmptyMessageAtTime(int what, long uptimeMillis);
然后开始创建线程
方式一:继承Thread类
步骤和java创建差不多,直接上程序
public class MyThread extends Thread{ public void run(){ //消息执行体,创建消息并发送到消息队列就在这里发送,如: Message message =new Message();//得到一个消息对象 message.what=1;//给消息做标记,当handler获取消息时就知道是那个 message.obj=msg;//需要发送的数据 mHandler.sendMessage(message);//向消息队列里加入消息 } }
开启线程的方法
MyThread myThread = new MyThread();//new一个线程对象 myThread.start();//使用start()方法启动线程
注意:不一定run()方法里的message都是用上面的方法创建,看情况而定
方式二:实现Runnable接口
直接上程序
public MyRunnable implements Runnable{ public void run(){ //消息执行体,创建消息并发送到消息队列就在这里发送,如: Message message =new Message();//得到一个消息对象 message.what=1;//给消息做标记,当handler获取消息时就知道是那个 message.obj=msg;//需要发送的数据 mHandler.sendMessage(message);//向消息队列里加入消息 } }
注意:有时根据需要可以通过写构造函数传入参数
启动线程方法
MyRunnable myRunable = new MyRunnable();//得到一个Runnable对象 Thread thread = new Thread(myRunnable);//new一个thread并传入runnable对象 thread.start();//使用start()方法启动线程
有时候为了看起来紧凑可以这样写
new Thread(new Runnable(){ public void run(){ //消息执行体,创建消息并发送到消息队列就在这里发送,如: Message message =new Message();//得到一个消息对象 message.what=1;//给消息做标记,当handler获取消息时就知道是那个 message.obj=msg;//需要发送的数据 mHandler.sendMessage(message);//向消息队列里加入消息 } }).start();
Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:
Handler mHandler=new Handler(); mHandler.post(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub } });
Runnable是一个接口,不是一个线程,一般线程会实现Runnable。 所以如果我们使用匿名内部类是运行在UI主线程的,如果我们使用实现这个Runnable接口的线程类,则是运行在对应线程的。
这种情况下,由于不是在新的线程中使用,所以千万别做复杂的计算逻辑。
下面给出简单例子(经典的在UI中实现计时操作)
XML布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <LinearLayout android:id="@+id/my_lay" android:layout_below="@id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="116dp" android:text="button" /> </LinearLayout> </RelativeLayout>
主程序
先做个简单的描述:
在这个例子里使用了上面的两种方式来创建线程,一个线程实现计时,一线程往TextView写入信息,Button按键按下计时停止
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; 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 final int MESSAGE_WHAT_1 = 1;//消息标记 private final int MESSAGE_WHAT_2 = 2; private final int MESSAGE_WHAT_3 = 3; public Button btn1 = null; private TextView tv = null; private TextView tv1 = null; private boolean isRunning = true;//计时 private int timer = 0; public Handler mHandler = null; private Thread mThread = null; private Thread mThread1 = null; private MyRunnable mRunnable = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=(TextView)findViewById(R.id.textView1); tv1=(TextView)findViewById(R.id.textView2); btn1=(Button)findViewById(R.id.button1); btn1.setOnClickListener(new bt1Listener()); mHandler = new MyHandler(); //线程1 mRunnable = new MyRunnable(); mThread = new Thread(mRunnable); mThread.start(); //线程2 mThread1 = new MyThread(); mThread1.start(); } public class MyHandler extends Handler{ public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_WHAT_2: //通过继承Thread类实现的线程更新UI String str1=msg.getData().getString("text1"); String str2=msg.getData().getString("text2"); tv.setText(str1 + " " + str2); case MESSAGE_WHAT_1: //通过实现Runnable来更新UI tv1.setText("逝去了:" + msg.obj);//经典的更新UI例子。在UI中计时 break; default: break; } } } //方法一:继承Thread类 public class MyThread extends Thread{ //private String data = ""; public MyThread(){//通过构造函数来传入数据 super(); } public void run(){ Message message=new Message();//new一个Message对象 message.what = MESSAGE_WHAT_2;//给消息做标记 Bundle bundle = new Bundle(); bundle.putString("text1","这个继承Thread类"); //往Bundle中存放数据 bundle.putString("text2","来更新UI"); //往Bundle中put数据 message.setData(bundle);//mes利用Bundle传递数据 mHandler.sendMessage(message);//Handler将消息放入消息队列 } } //方法二:实现implements接口 public class MyRunnable implements Runnable{ @SuppressWarnings("static-access") public void run(){ try { while(isRunning){ Thread.currentThread().sleep(1000); timer++;//加1计时 Message message = new Message();//new一个message对象 message.obj = timer;//将timer封装到消息里 message.what = MESSAGE_WHAT_1;//做标记 mHandler.sendMessage(message);//加入消息队列 } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } class bt1Listener implements OnClickListener{ @Override public void onClick(View arg0) { // TODO Auto-generated method stub isRunning = false; } }; @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; } }
效果图:
点击Button
其实android实现多线程的方法可采用runOnUiThread,post,handle,AsyncTask技术实现。
这里讲解的是使用handler,其他的由大家来。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories