listview 可以暂时告一段落了。。。
下面说说android的多线程机制,讲到多线程,就可以说道android有名的ANR(Application Not Responding)既应用程序未响应,触发ANR的条件大致有两个:1、在activity中超过5秒的时间未能响应下一个事件。2、BroadcastReceive超过10秒,这两个条件都会触发ANR。
下面模拟一个activity的ANR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button1).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { try { Thread.sleep( 10000 ); } catch (InterruptedException e) { e.printStackTrace(); } } }); } |
运行效果:
未触发:
触发后:
当用户使用时 出现这样的体验,可想而知会很蛋疼的。。。
有人就会问 为什么会有ANR这样的机制。
其实android系统中所有的UI显示都是在main线程中执行的,如果线程中有耗时操作时,线程中的其他UI组件就会等耗时结束时才能开始响应,所以为了避免这样的情况,android用handler将耗时操作放到子线程中执行,当结束时,将耗时操作的结果发回给主线程,所以这里又要引入线程间通信的概念
额(⊙o⊙)… 到这里感觉 新概念越写越多了。。。。 没事 慢慢解决么。。。
这么说感觉线程间通讯 很蛋疼 其实 也就调用一个方法而已。。。。
嘿嘿
不多说了 看代码先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | private Handler mHandler = new Handler() { //参数:Message相当于一种信息的载体,可以将子线程的数据传到主线程中,也就是所谓的线程间通信了。。。 public void handleMessage(android.os.Message msg) { //该方法在主线程中执行,不信的话可以log的。。。 String result = ( String ) msg.obj; //从主线程传来的数据 switch (msg.what) //what用于标记谁传来的信息 { case 1 : mTextView1.setText(result); //做UI组件的设置必须在主线程否则会报错的。。。 break ; case 2 : mTextView2.setText(result); break ; default : break ; } } }; private TextView mTextView1; private TextView mTextView2; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView1 = (TextView) findViewById(R.id.textView1); mTextView2 = (TextView) findViewById(R.id.textView2); Button button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(listener); Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(listener); } private OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: new Thread() { public void run() { // 模拟耗时操作 try { Thread.sleep( 1000 ); } catch (InterruptedException e) { e.printStackTrace(); } String result = "从网络获取的结果" ; Message msg = new Message(); msg.what = 1 ; msg.obj = result; // 发送到main线程 mHandler.sendMessage(msg); // textView.setText(result); } }.start(); Log.e( "MainActivity" , "button1" ); break ; case R.id.button2: new Thread() { public void run() { // 模拟耗时操作 try { Thread.sleep( 1000 ); } catch (InterruptedException e) { e.printStackTrace(); } String result = "从数据库获取的结果" ; Message msg = new Message(); msg.what = 2 ; msg.obj = result; // 发送到main线程 mHandler.sendMessage(msg); } }.start(); Log.e( "MainActivity" , "button2" ); break ; default : break ; } } }; |
我会把源代码 附加到文章的 布局文件 就不写了,占地方。。。
运行结果:
handler 差不多就这些了。。。代码的项目超过2mb 了 我放到51cto的网盘里了
下面讲讲 post,其实view.post和handle.post这两个方法差不多,都是在post方法中传入一个实现了Runnable接口的对象,在这个对象的run方法中实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | private TextView mTextView; private Button mButton; class Listener implements OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: download(); break ; default : break ; } } } @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.button1); mButton.setOnClickListener( new Listener()); } public void download() { new PlayThread().start(); //开启子线程 } class PlayThread extends Thread { @Override public void run() { // 这是子线程 try { Thread.sleep( 2000 ); //模拟从网络下载数据的耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } mButton.post( new Runnable() //这里用的是view的post方法 { //这里的内容将在主线程中显示 @Override public void run() { mTextView.setText( "yes 获取到数据了~~~" ); } }); } } |
runOnUiThread(Runnable action)方法和handler.post(Runnable action)方法,这两个方法的用法跟view.post(Runnable action)方法的用法一样
runOnUiThread(Runnable action)是activity的方法,这里的Runnable同样是运行在主线程中的
handler.post(Runnable action)是handler中的方法,大同小异,当然如果大家能告诉我这之间的区别我也会洗耳恭听的,相互学习么,谢谢啦。。。
本文出自 “android_home” 博客,请务必保留此出处http://yangzheng0809.blog.51cto.com/6024606/1271694
联系客服