A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Android Studio学习随笔-UI线程阻塞以及优化
我们在使用手机的时候,经常会遇到一个问题:先是卡死,然后跳出该程序无响应,是否关闭的提示(当然有可能是我们手机性能太差=。=)这是因为线程的阻塞引起的,在这里我讲述一下UI线程,一般处理程序会在UI线程中执行耗时操作,这回导致UI线程阻塞,当UI线程阻塞,屏幕会出现卡死,用户体验会变得非常差,当线程阻塞超过5s,android系统可能进行干预,弹出对话框询问是否关闭。那如何解决呢?
解决方案一:创建一个新线程
我在UI视图中创建了一个button和一个textView


    Button button=(Button)findViewById (R.id.button);       TextView textView=(TextView)findViewById(R.id.textView);        TranslateAnimation animation=new TranslateAnimation(0,200,0,0);        animation.setRepeatCount(3);        animation.setDuration(2000);        textView.setAnimation(animation);      //这里我让textView在进入app时进行移动动画        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(final View v) {//监听button的点击                new Thread(new Runnable() {//创建一个新线程                    @Override                    public void run() {                        try {                            Thread.sleep(5000);//在这里我让线程进行耗时操作                        }                        catch (InterruptedException e){
                e.printStackTrace();
              }                 }            }).start();        }
   });



上面的代码我创建一个新的线程来实现耗时,但是实际过程中进行的不可能只是一个耗时操作,让我们在新线程中加两句话,TextView view=(TextView)v;view.setText(""+100);(获取到当前控件,并将其文字设置成100)现在让我们再来试试这个程序,这个时候程序又报错了
Only the original thread that created a view hierarchy can touch its views.
翻译成中文就是:只有创建view的那个线程才能对其进行修改。
其实谷歌有两条建议,也可以说是规矩
there are simply two rules to Android's single thread model:    Do not block the Ui thread//不要阻塞UI线程    Do not access the Android UI toolkit from outside the UI thread//不要在UI线程外的其他线程对视图中的组件进行设置
那么很多人就有疑问了,这不是矛盾了吗?谷歌也为我们提供了解决方案
解决方案一:view.post
上面代码出错是因为我们在UI之外的线程调用了UI控件;那么现在,我们在try{}catch(){}语句后增加一下代码


1      v.post(new Runnable() {2                            @Override3                            public void run() {4                                TextView view=(TextView)v;5                                view.setText(""+sun);6                            }7                        });


这段代码将我的语句提交到了UI线程中;但是view.post也有一些缺点
冗余,可读性差,维护性差
为此官方也提供了另外一种解决方法
解决方法二:AsyncTask
AsyncTask和post方法大同小异
[url=][/url]
  private class DownloadImageTask extends  AsyncTask<String ,Void,Integer>{        protected Integer   doInBackground(String...urls){            try{                Thread.sleep(5000);            }catch (InterruptedException e){                e.printStackTrace();            }            int sun=100;            return  sun;        }        protected void onPostExecute(Integer sum){            button2.setText(""+sum);        }    }



button2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new DownloadImageTask().execute();                }           });

我们现在外部创建一个方法,然后在button的onClick事件中引用。


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马