Android 线程处理

12年前

1.多线程的两种实现方式:

  1. Thread.
    1. join().等待当前线程执行完毕后,才允许为其他线程的执行,如果此线程中断产生InterruptedException异常。
    2. yield().让此线程暂停执行,先让其他线程执行
    3. start(),run(),setPriority()...
  2. Runnable.
    1. 只需实现run(),但没有启动线程的start()方法,因此需要使用Thread类

2.线程安全:线程同步synchronized。可以用作线程方法和线程块。

//synchronized自成一个区块,可以灵活的指定对象与程序区块  synchronized(this){     code...  }

3.多线程的互动处理wait()和notify()

  1. notify()只会唤醒同一个对象但处于wait()状态的线程。
  2. 这两个方法定义在Object类中,任何对象都可以使用,但必须在synchronized域中才可以调用,否则illegalMonitorStateException异常。
  3. 避免相互等待-死锁
4.线程通信。

UI线程(管理用户界面的线程)是不安全的,不要阻塞ui线程、确保只在ui线程中访问ui组件也就是说只能在UI线程中修改UI组件,不应出现在后台线程中修改的UI组件的情况。比较耗时的工作最好在后台进行,否则可能阻塞UI界面

主要有两种方式:

  1. handler.通过显式的抛出和捕获消息,与UI进行交互。
    1. Message. Message保存了后台返回的数据,可以存储bundle等数据形式。 messageQueue是线程对应looper的一部分,负责存储从后台进程中抛回的和当前handler绑定的message,是一个队列。
      1. 实现handleMessage()
      2. obtainMessage()获取Message对象
      3. sendMessage()
    2. Runnable.
      1. Activity.runOnUiThread(Runnable)
      2. View.post(Runnable)
      3. View.postDelayed(Runnable, long)
  2. AsyncTask - AsyncTask<Params, Progress, Result>
    1. Params 启动任务执行的输入参数,比如HTTP请求的URL,Progress 后台任务执行的百分比。Result 后台执行任务最终返回的结果,比如String
    2. doInbackground().在后台线程中运行。
    3. onPostExcute(void result).UI线程中运行
    4. onProgressUpdate().doInBackground中调用了publishProgress之后,ui线程调用该方法,动态的改变进度条。

 

//下面提供一个简单的Asynctask的实例
class GetCSDNLogoTask extends AsyncTask<String, Integer, Bitmap>{  //String 传入参数类型,Integer 进度显示,Bitmap 返回值类型,这个类用于异步获取图片内容    @Override    protected Bitmap doInBackground(String... url) {     // TODO Auto-generated method stub     publishProgress(0); //将会调用onProgressUpdate(Integer... progress)     HttpClient client =new DefaultHttpClient();     publishProgress(30);     Log.i("log_out", url[0]);     HttpGet get=new HttpGet(url[0]);     final Bitmap bt;     try {      HttpResponse response =client.execute(get);      bt=BitmapFactory.decodeStream(response.getEntity().getContent());     } catch (ClientProtocolException e) {      return null;     } catch (IOException e) {      return null;     }     publishProgress(100);     return bt;    }    @Override    protected void onCancelled() {     progressBar.setProgress(0);    }    @Override    protected void onCancelled(Bitmap result) {     progressBar.setProgress(0);    }    @Override    protected void onPostExecute(Bitmap result) {     if(result != null){      Toast.makeText(AsyncTaskActivity.this, "success to get the logo...", Toast.LENGTH_LONG).show();      imgView.setImageBitmap(result);      Log.i("Log_out","img setting...");     }else {      Toast.makeText(AsyncTaskActivity.this, "failed...", Toast.LENGTH_LONG).show();     }    }    @Override    protected void onPreExecute() { //在doInBackground()之å‰�会被调用,在ui线程执行     imgView.setImageBitmap(null);     progressBar.setProgress(0);      }    @Override    protected void onProgressUpdate(Integer... progress) {//更新进度æ�¡è¿›åº¦     progressBar.setProgress(progress[0]);    }    }