Android 线程处理
1.多线程的两种实现方式:
- Thread.
- join().等待当前线程执行完毕后,才允许为其他线程的执行,如果此线程中断产生InterruptedException异常。
- yield().让此线程暂停执行,先让其他线程执行
- start(),run(),setPriority()...
- Runnable.
- 只需实现run(),但没有启动线程的start()方法,因此需要使用Thread类
2.线程安全:线程同步synchronized。可以用作线程方法和线程块。
//synchronized自成一个区块,可以灵活的指定对象与程序区块 synchronized(this){ code... }
3.多线程的互动处理wait()和notify()
- notify()只会唤醒同一个对象但处于wait()状态的线程。
- 这两个方法定义在Object类中,任何对象都可以使用,但必须在synchronized域中才可以调用,否则illegalMonitorStateException异常。
- 避免相互等待-死锁
UI线程(管理用户界面的线程)是不安全的,不要阻塞ui线程、确保只在ui线程中访问ui组件也就是说只能在UI线程中修改UI组件,不应出现在后台线程中修改的UI组件的情况。比较耗时的工作最好在后台进行,否则可能阻塞UI界面
主要有两种方式:
- handler.通过显式的抛出和捕获消息,与UI进行交互。
- Message. Message保存了后台返回的数据,可以存储bundle等数据形式。 messageQueue是线程对应looper的一部分,负责存储从后台进程中抛回的和当前handler绑定的message,是一个队列。
- 实现handleMessage()
- obtainMessage()获取Message对象
- sendMessage()
- Runnable.
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- View.postDelayed(Runnable, long)
- AsyncTask - AsyncTask<Params, Progress, Result>
- Params 启动任务执行的输入参数,比如HTTP请求的URL,Progress 后台任务执行的百分比。Result 后台执行任务最终返回的结果,比如String
- doInbackground().在后台线程中运行。
- onPostExcute(void result).UI线程中运行
- 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]); } }