Android 线程间的通信

目录

一、定义:

二、Thread类的使用方法

三、线程相关组件

1)职责

2)关系

3)消息循环

4)线程与更新

5)SDK提供了四种可以从其他线程访问UI线程:

6)总结


一、定义:

1、多线程:
              线程是程序中单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程。

如图:

 

2、ANR的三种情况:由于应用程序无响应从而出现对话框

  1. 主要类型按键或触摸事件在特定时间(5s)内无响应
  2. BroadcastReceiver在特定时间(10s)内无法处理完成
  3. 小概率类型Service在特定时间内无法处理完成

 

二、Thread类的使用方法

1、线程中的常用方法:

  1. start()方法:启动线程
  2. run()方法:不需要用户调用,继承Thread类必须重写run()方法
  3. sleep()方法:sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务

2、线程的状态:

  1. 创建(new)
  2. 就绪(runnable)
  3. 运行(running)
  4. 阻塞(blocked)
  5. time wating
  6. 消亡(dead)
  7. interrupt方法:  中断,单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常(可以用来中断一个正处于阻塞状态的线程),另外,通过interrupt方法和isInterrupted方法来停止正在运行的线程

 

3、上下文切换:

       CPU在一个时刻只能运行一个线程,挡在云想一个线程的过程中去运行另一个线程时,叫做上下文切换。在切换时,需要保存线程的状态

代码内有解释:

//用买票来表示线程
package com.example.thread2;

import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

	public final String TAG = "Thread2";
	private Button mButton;
	//线程  SaleTicket
	private SaleTicket mSaleTicket;

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

		mButton = (Button) findViewById(R.id.bt_button);
		mButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				//线程开始,通过接口来设置Thread的名字
				new Thread(mSaleTicket, "队伍一").start();
			}
		});
		//传入值为10
		mSaleTicket = new SaleTicket(10);
	}

	private class SaleTicket implements Runnable {

		private int tickets = 0;

		public SaleTicket(int tickets) {
			this.tickets = tickets;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (tickets > 0) {
				sale();
			}
			Log.d(TAG, "" + Thread.currentThread().getName() + ": 票卖完了");
		}

		private void sale() {
			tickets--;
			Log.d(TAG, "" + Thread.currentThread().getName() + " :买了一张票,还剩下 "
					+ tickets + " 张票");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

三、线程相关组件

1)职责

1、Message:消息,其中包括了消息ID,消息处理对象以及处理的数据等。Message由MessageQueue统一队列,终由Handler处理。

2、Handler:处理者,负责Message的发送及处理。实现HandlerMessage(Message msg)方法对特定的Message进行处理。

3、MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。

4、Looper:消息泵,不断从MessageQueue中抽取Message执行。一个MessageQueue需要一个Looper。

5、Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

2)关系

1、Handler、Looper和MessageQueue是最简单的三角关系,Looper和MessageQueue是一一对应的。

2、创建一个Looper同时,会创建一个MessageQueue,Handler、Looper和MessageQueue是最简单的聚焦关系。

3、多个Handler都可以共享同一个Looper和MessageQueue了。当然这些Handler也都运行在同一个线程里。

3)消息循环

4)线程与更新

5)SDK提供了四种可以从其他线程访问UI线程:

  1. Activity.runOnUiThread(Runnable)
  2. View.post(Runnable)
  3. View.postDelayed(Runnable,long)
  4. Handler

6)总结

  1. Handler的处理过程运行在创建Handler的线程里。
  2. 一个Looper对应一个MessageQueue
  3. 一个线程对应一个Looper
  4. 一个Looper可以对应多个Handler
  5. 不确定当线程时,更新UI时尽量调用post方法

代码:

package com.example.handlerdemo;

import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class MainActivity extends ActionBarActivity {

	private final String TAG = "Handler";
	private Button mButton;
	private TextView mMsgTextView;

	private Handler mMainHandler;
	private Handler mChildHandler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// init for ui
		mButton = (Button) findViewById(R.id.bt_button);
		mMsgTextView = (TextView) findViewById(R.id.tv_msg);

		mButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View view) {
				// TODO Auto-generated method stub
				Message msg = mMainHandler.obtainMessage();

				Bundle bundle = new Bundle();
				bundle.putString("name", "zhangsan");
				bundle.putInt("age", 23);

				msg.setData(bundle);
				msg.what = 100;
				msg.obj = "Hello";
				//发送消息
				mChildHandler.sendMessage(msg);
			}
		});
		mMainHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				String text = (String) msg.obj;
				mMsgTextView.setText(text);
			}
		};

		new ChildThread().start();
	}

	private class ChildThread extends Thread {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			//初始化消息队列的参数
			Looper.prepare();
			mChildHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
					int what = msg.what;
					Bundle bundle = msg.getData();
					String name = bundle.getString("name");
					int age = bundle.getInt("age");
					Log.d(TAG, "name = " + name + ", age = " + age);

					Log.d(TAG, "what = " + what);
					String text = (String) msg.obj;
					text += ", World!";
					Message message = mChildHandler.obtainMessage();
					message.obj = text;
					mMainHandler.sendMessage(message);
				}
			};
			// 开启消息队列
			Looper.loop();
		}
	}

}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值