Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例

1.Handler

接到上一篇。

上一篇有3个通知主线程(UI线程),并让主线程来执行代码的方法。现在我们要接触的是稍微复杂一点的方法Handler和AsyncTask,当然,我们可以用这两个来做更多的工作。

参考:

http://www.vogella.com/articles/AndroidPerformance/article.html

http://developer.android.com/reference/android/os/Handler.html

通知主线程的方法有post(Runnable),postAtTime(Runnable, long), postDelayed(Runnable, long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message, long), andsendMessageDelayed(Message, long),每个都写个例子吧。

1.1 post(Runnable)

postAtTime(Runnable, long)postDelayed(Runnable, long)我就不写了哈

参数点击进去可以参考官方文档。使用跟post(Runnable)一样。


MainActivity.java


package com.example.testdialog;  
  
import android.os.Bundle;  
import android.os.Handler;
import android.app.Activity;  
import android.view.Menu;  
import android.widget.TextView;
      
    public class MainActivity extends Activity {  
          
        private TextView mTextView;
        private Handler handler = new Handler();
          
        public class CountThread extends Thread {
            private int i;
            
            @Override  
            public void run() { 
                for(i=0; i<100; i++) {
                    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    /**
                     * 线程跑到哪里了
                     */
                    handler.post(new Runnable() {  
                        public void run() {  
                            mTextView.setText(String.valueOf(i));  
                        }  
                    });  
                }
                
                /**
                 * 
                 */
                handler.post(new Runnable() {  
                    public void run() {  
                        mTextView.setText("线程跑完了!");  
                    }  
                }); 
            }  
        }  
          
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
              
            mTextView = (TextView)findViewById(R.id.textView1);  
              
            /**
             * 启动线程
             */
            (new CountThread()).start();  
              
        }  
      
        @Override  
        public boolean onCreateOptionsMenu(Menu menu) {  
            getMenuInflater().inflate(R.menu.activity_main, menu);  
            return true;  
        }  
    }  
结果:

Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例_第1张图片

Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例_第2张图片

可能有的童鞋说我不用线程也可以做这个,是的,但是如果不用线程的话,你在跑的过程中点击菜单按钮试试,看有没有反应?


1.2sendMessage(Message)

package com.example.testdialog;  
  
import android.os.Bundle;  
import android.os.Handler;
import android.os.Message;
import android.app.Activity;  
import android.view.Menu;  
import android.widget.TextView;
      
    public class MainActivity extends Activity {  
          
        private Handler handler; 
        
        static class TestHandler extends Handler{

        	private TextView mTextView;
        	/**
        	 * 我创建这个构造函数式因为我需要把这个handler类
        	 * 声明成static的,如果不声明成static的话会有个警告,
        	 * 因为就那么一个警告,想去掉。所以。。。
        	 * @param textView
        	 */
        	TestHandler(TextView textView) {
        		TestHandler.this.mTextView = textView;
        	}
			@Override
			public void handleMessage(Message msg) {
				// 在线程里面sendMessage
				//在handler里面就需要处理这些消息
				switch(msg.what) {
					case CountThread.THREAD_START:
						mTextView.setText("线程启动啦,还带了两个参数:\n" + 
								msg.getData().getString("param1") + "\n" + 
								msg.getData().getString("param2"));
						break;
					case CountThread.THREAD_LOOP:
						mTextView.setText("线程正在运行循环,还带了个参数:\n" + 
								msg.getData().getInt("i"));
						break;
						
					case CountThread.THREAD_END:
						mTextView.setText("线程运行结束了!");
						break;
				}
				super.handleMessage(msg);
			}
        	
        };
          
        public class CountThread extends Thread {
        	
        	/**
        	 * 自己定义一些常量,只是为了更有意义,通过看名称就知道意思
        	 */
        	public static final int THREAD_START = 0;
        	public static final int THREAD_LOOP = 1;
        	public static final int THREAD_END = 2;
        	
            private int i;
            
            @Override  
            public void run() { 
                /**
                 * 你可以定义消息类型,可以带不同类型的参数
                 */
            	Message msg = new Message();
                msg.what = THREAD_START;
                Bundle bundle = new Bundle();
                bundle.putString("param1", "这是第一个参数!");
                bundle.putString("param2", "这是第二个参数!");
                msg.setData(bundle);
            	handler.sendMessage(msg);	//发送消息
            	
                for(i=0; i<100; i++) {
                    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    /**
                     * 线程跑的进度
                     */
                   msg = new Message();
                   bundle = new Bundle();
                   bundle.putInt("i", i);
                   msg.setData(bundle);
                   msg.what = THREAD_LOOP;
                   handler.sendMessage(msg); 	//发送消息
                }
                
                msg = new Message();
                msg.what = THREAD_END;		
                handler.sendMessage(msg);	//发送消息
                
            }  
        }  
          
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
              
            handler = new TestHandler((TextView)findViewById(R.id.textView1));
              
            /**
             * 启动线程
             */
            (new CountThread()).start();  
              
        }  
      
        @Override  
        public boolean onCreateOptionsMenu(Menu menu) {  
            getMenuInflater().inflate(R.menu.activity_main, menu);  
            return true;  
        }  
    }  
结果:

Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例_第3张图片

结论:如果想带个参数的话,最好用sendMessage,如果需要反馈的信息很少,可以用post


2.AsyncTask

package com.example.testdialog;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {

	private TestTask mTask;

	private TextView mTextView;

	/**
	 * AsyncTask<String, Integer, Long> 第一个是doInBackground的参数类型
	 * 第二个是onProgressUpdate的参数类型 第三个是onPostExecute的参数类型
	 * 
	 */
	private class TestTask extends AsyncTask<Integer, Integer, Long> {

		/**
		 * 注意哦,这个参数是String[]
		 */
		protected Long doInBackground(Integer... intArr) {

			int count = intArr[0];

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long totalSize = 0;
			for (int i = 0; i < count; i++) {
				// 注意,待会儿我要把这个循环设置1000000,让大家看看cancel的效果
				// 每次调用这个都会发送消息,然后主线程执行onProgressUpdate
				this.publishProgress(i); 
				if (isCancelled())
					break;
				totalSize++;
			}
			return totalSize; //这个是会被当做参数传到onPostExecute
		}

		protected void onProgressUpdate(Integer... progress) {
			mTextView.setText("现在循环进行到:" + progress[0]);
		}

		/**
		 * 在doInBackground之前会执行
		 */
		@Override
		protected void onPreExecute() {
			mTextView.setText("现在doInBackground还没有执行...");
		}

		/**
		 * 在调用AsyncTask.cancel的时候会执行
		 */
		@Override
		protected void onCancelled() {
			mTextView.setText("点击返回按钮了");
		}

		/**
		 * 在doInBackground执行完成后
		 */
		protected void onPostExecute(Long result) {
			mTextView.setText("测试AsyncTask结束了,\n循环了" + result + "次。");

		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mTextView = (TextView) findViewById(R.id.textView1);
		mTask = new TestTask();
		mTask.execute(1000000); // 看,亲,是百万次哦

	}

	// 按返回键的时候会触发
	@Override
	public void onBackPressed() {
		mTask.cancel(false);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
}

结果:

Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例_第4张图片


当点击返回按钮时,就不循环了,当循环到1000000次的时候(下面这张图是我把数量改成了10000次截的图,哈哈)

Android 学习笔记 Thread (二) android线程 Handler,AsyncTask例_第5张图片


一个简单的Handler和SyncTask的例子。


你可能感兴趣的:(thread,thread,android,android,handler,handler,SyncTask)