麦都-平台开发组

Android的线程的理解和应用

写作时间:2018-05-08

一、android线程的定义和特点

          1、什么是线程:

                  线程是一种轻量级进程,大多数情况下用于执行异步操作。在一个android程序开始运行的时候,会单独启动一个进程,同时会产生一个UIThread线程(主线程)。一个android程序默认情况下只有一个进程,但是一个进程下可以有多个线程。

          2、线程与进程的区别:

                (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;

                (2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源

                (3)线程是处理器调度的基本单位,但进程不是

                (4)线程只需要很少的资源就可“轻装上阵”运行的优点,来弥补进程并发的“颗粒度”粗糙的缺点,提高系统资源(如:CPU,内存——又可分为数据区,堆栈区等等,和IO总线控制权……)利用率。


二、为什么要用线程?

           1、用于异步操作

           2、默认的情况下,Service和Activity(还有Content Provider和Broadcast Receiver)会同时运行在进程的main线程中,是会相互阻塞的。因此要在服务中执行长时间的操作(如网络应用)时,还是要自己创建线程来操作。


三、线程的实现方法

          1、继承java.lang.Thread类,重载它的run()方法和start()函数来启动线程:

     Thread thread=new Thread(new Runnable(){    

            @Override    
            public void run() {    
                 Message message =  new Message();                   
                 message.what=1;    
                 mHandler.sendMessage(message);  
                 } 
     )};
     thread.start();

           2、实现Runnalbe接口,重载它的run()方法,用start()函数来启动线程: 

public class Runnalble_Demo extends Activity implements Runnable {

      public Button button;    

      public LinearLayout my_layout;            

      public Handler mHandler=new Handler() {    

            public void handleMessage(Message msg){    

                  switch(msg.what) {    

                      case 1:                   

                          button.setText(R.string.text2);    

                      break;              

                      default:    

                      break;     

                  }    

           my_layout.invalidate();    

           super.handleMessage(msg);     

       };        /** Called when the activity is first created. */ 
  
       @Override       
       public void onCreate(Bundle savedInstanceState){    

           super.onCreate(savedInstanceState);                       

           my_layout=(LinearLayout)findViewById(R.id.my_layout);   

            Thread thread=new Thread(this);       

       }      

       @Override  

        public void run()  {    

              Message message =  new Message();                   
              message.what=1;    
              mHandler.sendMessage(message);  
        }   

 }


三、既然说的是Android,我们不得不提到的是AsyncTask

          AsyncTask是Android框架提供的异步处理的辅助类,它可以实现耗时操作在其他线程执行,而处理结果在Main线程执行。使用他你会发现你的代码很容易被理解,因为他们都有一些具有特定职责的方法,尤其是AsyncTask,有预处理的方法onPreExecute,有后台执行任务的方法doInBackground,有更新进度的方法publishProgress,有返回结果的方法onPostExecute等等。不过封装越好越高级的API,对初级程序员反而越不利,就是你不了解它的原理。当你需要面对更加复杂的情况,而高级API无法完成得很好时,你就杯具了

public void onClick(View v){

        new DownloadImageTask().execute("http://gkimg.cdn.midasjoy.com/Uploads/picture/20171026/59f17bbeb0218.png");

}

private class DownloadImageTask  extends AsyncTask{

          protected Bitmap doInBackground(String ... urls){

                return  loadImageFromNetWork(urls[0]);//加载网络图片的方法,此处略

          }

          protected  void onPostExecute(Bitmap result){

                mImageView.setImageBItmap(result);

          }

}


四、那么,继承Thread类与实现Runnable接口有什么区别?优缺点?  

           1、Thread 类实现了Runnable接口

            2、在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.

                    如果自定义线程类继承自Thread,那么它无法再继承其他类,拥有其他类的方法,降低了类的扩展性。但是,如果通过实现Runnable接口,你就可以继承其他类了。

            3、还有一点最重要,就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享:

                    比如模拟一个火车站的售票系统,假如只有100张火车篇,且允许所有窗口卖这100张票,那么每一个窗口也相当于一个线程,但需要处理的资源是同一个资源,即100张车票。如果还用前面的方式来创建线程显然是无法实现的,这种情况该怎样处理呢?看下面这个程序:

public class MutliThreadDemo {    

     public static void main(String[] args) {            
          MutliThread m=new MutliThread();     
          Thread t1=new Thread(m);      
          Thread t2=new Thread(m);     
          Thread t3=new Thread(m);
          t1.start();
          t2.start();     
          t3.start();    
     } 

    public class MutliThread implements Runnable{     
          private int ticket=100;//每个线程都拥有100张票          
          public void run(){     
          while(ticket>0){                  
              System.out.println(ticket--+" is saled by "+Thread.currentThread());     
          }     
    } 
}

 

            程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。