Android 线程

  1. 当应用启动,系统会创建一个主线程,也叫UI线程,系统对每个UI组件的调用事件都在UI线程中分发出去,而不会为每个UI单独建立线程,这种单线程模型有两个准则:
    • 不要阻塞UI线程
    • 不能在UI线程之外访问Android UI

  2. 下面方法可以将执行放在UI线程,但不常用
    • Activity.runOnUiThread(Runnable)
    • View.post(Runnable)
    • View.postDelayed(Runnable, long)

  3. Handler类的主要作用:
    • 在新启动的线程中发送消息,调用sendMessage系列函数
    • 在主线程中获取,处理消息,当新线程发送消息时,主线程会回调handleMessage方法进行处理
      HandlerHandler myHandler = new Handler() {  
                public void handleMessage(Message msg) {   
                     switch (msg.what) {   
                          case TestHandler.GUIUPDATEIDENTIFIER:   
                               myBounceView.invalidate();  
                               break;   
                     }   
                     super.handleMessage(msg);   
                }   
           };  
      
      Message msg=new Message()
      msg.what=0x123
      myHandler.sendmessage(msg)

  4. 要使用Handler线程中还要有一个Looper对象,负责管理MessageQueue,不间断的从MessageQueue中取出消息分发给Handler来处理,注意UI线程中已经初始了一个Looper对象,程序直接创建Handler即可,自己启动的线程,必须自己去创建Looper对象并启动它,自定义线程使用Handler和Looper的过程如下:
    • 调用Looper.prepare() 创建一个Looper对象
    • 创建Handler对象并重写handleMessage方法
    • 调用Looper的loop方法来启动Looper
  5. 一个线程只能有一个Looper,但可以有多个Handler对象,每个Handler发送的消息由这个Handler本身处理。ActivityThread中定义了一个Handler,用于与ApplicationThread通信
  6. 异步任务AsyncTask,通常要实现AsyncTask的如下方法:
    • onPreExecute:执行异步任务之前的时候执行,并且在UI线程中执行,通常在这个方法里做一些UI控件的初始化的操作
    • doInBackground:在onPreExecute后执行,android会在后台的线程池中开启一个work thread来执行我们的方法,之后会把执行结果发送给onPostExecute方法
    • onProgressUpdate:在doInBackground方法中调用publishProgress方法更新任务进度时会触发该方法
    • execute:执行task
      实现AsyncTask public class MyAsyncTask extends AsyncTask<String, Integer, byte[]>
          {
              @Override
              protected void onPreExecute()
              {
                  super.onPreExecute();
                  //    在onPreExecute()中我们让ProgressDialog显示出来
                  progressDialog.show();
              }
      
              //返回的结果会传给onPostExecute
              @Override
              protected byte[] doInBackground(String... params)
              {
                  //    通过Apache的HttpClient来访问请求网络中的一张图片
                  HttpClient httpClient = new DefaultHttpClient();
                  HttpGet httpGet = new HttpGet(params[0]);
                  byte[] image = new byte[]{};
                  try
                  {
                      HttpResponse httpResponse = httpClient.execute(httpGet);
                      HttpEntity httpEntity = httpResponse.getEntity();
                      InputStream inputStream = null;
                      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                      if(httpEntity != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
                      {
                          //    得到文件的总长度
                          long file_length = httpEntity.getContentLength();
                          //    每次读取后累加的长度
                          long total_length = 0;
                          int length = 0;
                          //    每次读取1024个字节
                          byte[] data = new byte[1024];
                          inputStream = httpEntity.getContent();
                          while(-1 != (length = inputStream.read(data)))
                          {
                              //    每读一次,就将total_length累加起来
                              total_length += length;
                              //    边读边写到ByteArrayOutputStream当中
                              byteArrayOutputStream.write(data, 0, length);
                              //    得到当前图片下载的进度
                              int progress = (int)((total_length/(float)file_length * 100));
                              //    时刻将当前进度更新给onProgressUpdate方法
                              publishProgress(progress);
                              //为了看出进度条效果,让程序慢点执行
                              Thread.sleep(1000);
                          }
                      }
      
                      //转换为byte数组 返回给onPostExecute
                      image = byteArrayOutputStream.toByteArray();
                      inputStream.close();
                      byteArrayOutputStream.close();
                  }
                  catch (Exception e)
                  {
                      e.printStackTrace();
                  }
                  finally
                  {
                      httpClient.getConnectionManager().shutdown();
                  }
                  return image;
              }
              @Override
              protected void onProgressUpdate(Integer... values)
              {
                  super.onProgressUpdate(values);
                  //    更新ProgressDialog的进度条
                  progressDialog.setProgress(values[0]);
              }
              @Override
              protected void onPostExecute(byte[] result)
              {
                  super.onPostExecute(result);
                  //    将doInBackground方法返回的byte[]解码成要给Bitmap
                  Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
                  //    更新我们的ImageView控件
                  imageView.setImageBitmap(bitmap);
                  //    使ProgressDialog框消失
                  progressDialog.dismiss();
              }
          }

  7. 使用AsyncTask时必须遵守如下规则:
    • 必须在UI线程中初始化AsyncTask的实例
    • 必须在UI线程中调用AsyncTask的execute方法
    • AsyncTask的onPreExecute,onPostExecute,doInBackground,onProgressUpdate方法不能由程序员自己调用,而是由Android系统负责调用
    • 每个AsyncTask只能执行一次,多次调用将引发异常
       

posted on 2014-09-12 21:21 哨兵 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/phenixyu/p/3969094.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值