解决UI主线程阻塞原因
2016-04-06 23:36
507 查看
了解进程和线程的区别,在进行耗时操作遇到阻塞时,学会线程阻塞时的处理方法。
当线程阻塞超过5秒时,会遭到系统的提示解决阻塞的问题的方法:
(1)创建一个新的进程
官方建议:不要阻塞UI进程;
不要在UI进程之外的其他线程中,对视图当中的组件进行设置。
//经典异常
Only the original thread that created a
view hierarchy can touch its views.
只有创建view的那个线程才能对其进行修改。
解决异常的方法:
(1)用post来解决。(弊端:代码复杂度增加了,
因为可读性差了,所以维护性也就差了)
(2)最佳的解决法案:用AsyncTask来解决。(例子
在test_thread实例里面)(其实这里并不是最佳,应该比较AsyncTask和handl机制的区别,这两种解决方案在不同场合下的应自己分析使用)
(3)用handle机制的解决方案:采用handle机制来实现子线程发送message通知主线程去改变UI组件。
代码如下:## 这个是上面的AsyncTask和post方案的比较的实例代码 ##
当线程阻塞超过5秒时,会遭到系统的提示解决阻塞的问题的方法:
(1)创建一个新的进程
官方建议:不要阻塞UI进程;
不要在UI进程之外的其他线程中,对视图当中的组件进行设置。
//经典异常
Only the original thread that created a
view hierarchy can touch its views.
只有创建view的那个线程才能对其进行修改。
解决异常的方法:
(1)用post来解决。(弊端:代码复杂度增加了,
因为可读性差了,所以维护性也就差了)
(2)最佳的解决法案:用AsyncTask来解决。(例子
在test_thread实例里面)(其实这里并不是最佳,应该比较AsyncTask和handl机制的区别,这两种解决方案在不同场合下的应自己分析使用)
(3)用handle机制的解决方案:采用handle机制来实现子线程发送message通知主线程去改变UI组件。
代码如下:## 这个是上面的AsyncTask和post方案的比较的实例代码 ##
package com.example.test_thread; import android.app.Activity; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.TranslateAnimation; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button button2=null;//把button2设置成成员变量 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = (Button) findViewById(R.id.button1); // TranslateAnimation是位移的动画效果 TranslateAnimation animation = new TranslateAnimation(0, 150, 0, 100); animation.setRepeatCount(30);// 设置动画重复多少次 animation.setDuration(3000);// 设置动画的效果时间 button1.setAnimation(animation); button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new OnClickListener() { // 当线程阻塞超过5秒时,会遭到系统的提示 @Override // 这里的v其实就是Button2对象 public void onClick(final View v) {/* // /用Thread.currentThread().getId()来进行观看post与 // UI主线程是一致的 System.out.println(Thread.currentThread().getId()); new Thread(new Runnable() { @Override public void run() { System.out.println("线程开始执行。。。。"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } v.post(new Runnable() { public void run() { System.out.println("post开始执行。。。。"+ Thread.currentThread().getId()); TextView view = (TextView) v;// 用view来接收v view.setText("" + 10); } }); System.out.println("线程结束执行。。。。"); } }).start(); */ new DownloadImageTask().execute(); } }); } private class DownloadImageTask extends AsyncTask<String,Void,Integer>{ /**The system calls this to perform work in a worker thread and * delivers it the parameters given to AsyncTask.excute() */ protected Integer doInBackground(String... urls) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } int sum=10; return sum; } /**The system calls this to perform work in the UI thread and delivers * the result from doInBackground() */ protected void onPostExecute(Integer sum){ //把button2设置成成员变量就可以调用setText button2.setText(""+sum); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
相关文章推荐
- Ruby中的异常处理代码编写示例
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- MySQL抛出Incorrect string value异常分析
- Android AsyncTask源码分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- 浅谈C#中简单的异常引发与处理操作
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- 详解C#编程中异常的创建和引发以及异常处理
- ASP.NET线程相关配置