Android之线程

对android的单线程模型,有两个简单的规则
1、不阻塞UI线程

2、不从UI线程之外访问ANDROID的UI工具,即不在UI线程之外更新UI

工作线程
由于上面对线程模型的规则,不阻塞UI线程,对应用的UI反应是至关重要的
如果操作不是瞬间就能完成的话,需要保证该工作运行在单独的线程中

例如下面的程序,在一个线程中下载一个图片,并且显示在ImageView中

	public void onClick(View v) {
  	  new Thread(new Runnable() {
   	     public void run() {
   	         Bitmap b = loadImageFromNetwork("http://example.com/image.png");
   	         mImageView.setImageBitmap(b);
   	   	  }
  		  }).start();
		}

虽然上面的程序运行起来很好,并且创建了一个单独的线程来处理网络操作,但是违反了第二个原则
该例子在工作线程中修改ImageView,而不是UI线程中,可能产生未定义或者是意想不到的结果
为了弥补这个错误,ANDROID中提供了几种在线程中访问UI的方法,
下面是这些方法的列表

	Activity.runOnUiThread(Runnable)
	View.post(Runnable)
	View.postDelayed(Runnable, long)


例如用View.post方法来修复上面的BUG

	public void onClick(View v) {
    	new Thread(new Runnable() {
       	 public void run() {
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
     	       });
     	   }
   		 }).start();
	}

当前的实现时线程安全的,网络操作是从一个单一的线程,同时ImageView从UI线程中设置
然而,当操作的复杂性增加的时候,这种代码的变得很难维护。为了解决这种工作线程的复杂操作,或许可以考虑利用Handler来


处理UI线程发来的消息。或许最好的解决方法是来继承AsyncTask类,该类简化了工作线程需要和UI交互的任务


AsyncTask 允许在用户界面执行异步工作,她可以阻断工作线程,然后将结果发布到UI线程中,不需要自定义处理线程
使用该方法的时候,需要继承AsyncTask 并且实现doInBackground()回调方法,该方法运行在一个后台线程池中
为了更新UI,还必须实现onPostExecute()方法,该方法将doInBackground()中的结果发送到UI线程中并且运行起来。因此可以安全的更新UI。

在UI线程中运行该任务需要调用execute()方法
例如用下面的方法实现上面的例子:

public void onClick(View v) {
    new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {

    protected Bitmap doInBackground(String... urls) {
        return loadImageFromNetwork(urls[0]);
    }
    
    protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }
}


 AsyncTask 工作的过程
1、可以利用泛型指定参数的类型,进度值和任务的最终结果
2、 doInBackground()方法在工作线程中自动的执行
3、onPreExecute(), onPostExecute(), and onProgressUpdate()都是在UI线程中被唤醒的
4、 doInBackground()中的 返回值被发送到onPostExecute()里
5、在doInBackground()中可以随时的调用publishProgress()方法来执行onProgressUpdate()方法对UI线程进行更新
6、可以在任何时候,从任意的线程中取消任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值