Android中在主线程与在子线程中更新UI的探索
来源:互联网 发布:如何修改电脑mac地址 编辑:程序博客网 时间:2024/05/21 06:56
今天在做一个运动的小球的安卓项目的时候,我尝试着在子线程中刷新ui。众所周知,子线程是线程中不安全的,这个不安全不是说不能在子线程里面更新UI,这个很复杂,取决于你的主线程处理的时间,子线程就是子线程,主线程就是主线程,不必太纠结,碰到一个问题,要善于去寻找他有价值的地方。在子线程中也可以用handler,不过这需要开启一个循环队列looper,并且用looperloop()方法,这主要是为了能够在子线程中创建handler,但是问题来了,loop()里面是一个循环,但是为了刷新,线程里面又是一个循环,两者不可同时进行,所以这样的方法handleMessage不会被执行,逻辑上不是很好。逻辑上出现了问题。
package wust.edu.ball; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; public class MoveActivity extends Activity { Handler handler=null; Thread t;//放在外面。这样比较好。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyView mv=new MyView(MoveActivity.this); setContentView(mv); } @Override protected void onStop() { // TODO Auto-generated method stu super.onStop(); System.out.println("OnDestroy有没有被执行"); t.stop(); t.interrupt(); t=null; } class MyView extends View implements Runnable{ private int x=20,y=20; public MyView(Context context) {//应用的上下文。 super(context); setFocusable(true); t=new Thread(this); t.start(); // TODO Auto-generated constructor stub } @Override public void run() { System.out.println("线程有没有被执行"); Looper.prepare(); handler=new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub System.out.println("handler方法有没有执行"); if(msg.what==0x11){ MyView.this.update();//不要局限于这个,你可以取得他的引用的 MyView.this.invalidate(); } super.handleMessage(msg); } }; while(!Thread.currentThread().isInterrupted()){ System.out.println("线程里面的方法有没有被执行"); Message m=Message.obtain(); m.what=0x11; handler.sendMessage(m); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }//已经进入循环 } Looper.loop();//监视循环队列。这里又是一个循环 } protected void update() { // TODO Auto-generated method stub System.out.println("update方法被执行了"); int h=MyView.this.getHeight(); y+=5; if(y>=h){ y=20; } } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); Paint p=new Paint(); p.setColor(Color.RED); canvas.drawCircle(x,y,15,p); } } }接下来。在一个网友的帮助下寻找到了正确的方法,就是最常规的方法,在主线程中更新ui,接下来看代码。
Handler mHandler = new Handler() {//主线程里面 @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if (msg.what == 0x11) { mv.update();//交给主线程去处理。 mv.invalidate(); } } }; private MyView mv;//持有类的(也可以是内部类的一个)对象。我老是不知道invalidate在那里面执行 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mv = new MyView(MoveActivity.this); setContentView(mv); new Thread() {//就是子线程,不要去纠结。 public void run() { while (!Thread.currentThread().isInterrupted()) { Message m = new Message(); m.what = 0x11; mHandler.sendMessage(m); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; }.start(); } class MyView extends View { private int x = 20, y = 20; public MyView(Context context) {// 应用的上下文。 super(context); setFocusable(true); // TODO Auto-generated constructor stub } protected void update() { // TODO Auto-generated method stub int h = MyView.this.getHeight(); int w = MyView.this.getWidth(); y += 5; x += 5; if (y >= h||x>=w) { y = 20; x = 20; } } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub System.out.println("这个方法被执行了几次"); super.onDraw(canvas); Paint p = new Paint(); p.setColor(Color.RED); canvas.drawCircle(x, y, 15, p); } } }这里要注意它的一个方法,也是在面向对象中比较常见的一个方法,持有类的引用,这里最关键的是,他吧内部类Myview的引用申明为了全局变量,这样的话就可以访问它的update和invalidate方法了,这个思路比较好的,面向对象的核心。
总之还是那句话,在安卓里面,主线程是线程中不安全的,一般来说不允许在子线程中更新ui。但是还是要灵活解决。
0 0
- Android中在主线程与在子线程中更新UI的探索
- Android 在子线程中更新主线程UI
- android 橘子汁 在子线程中更新主线程UI 困扰
- Android显示系统之View与SurfaceView更新屏幕的区别.对于View.则是在UI主线程中更新画面.SurfaceView更新屏幕,是在非UI线程(主线程)中实现SurfaceHolde
- Handler post()等在子线程中更新主线程的UI的方法使用小汇
- android-----在子线程中更新UI操作的方法
- android中UI主线程与子线程深入分析
- Android中UI主线程与子线程
- 在Android中,非主线程不能更新UI
- Android线程模型--在子线程中更新UI
- 在子线程中更新UI
- 在子线程中如何更新ui
- 在子线程中更新UI
- 在子线程中更新UI
- 在子线程中更新UI
- android如何在子线程中更新UI
- Android Service——在子线程中更新UI
- android 学习 在子线程中更新UI
- 关于高精度问题的自我总结
- PHP类的静态方法和静态变量
- 手机号码验证,邮箱,车牌验证
- zoj-1789
- 黑马程序员------- IO-------
- Android中在主线程与在子线程中更新UI的探索
- 半年C++学习有感
- Fermat vs. Pythagoras -基础数论(深刻总结)
- linux 的ioctl()函数
- 小强的HTML5移动开发之路(16)——神奇的拖放功能
- JQuery移除一个元素
- 最简单的win32汇编程序
- SQL Server还原数据库操作详细步骤
- Exponentiation -高精度求幂的自我总结