安卓中控制线程其实我们之前在JAVA中原理并没有多少区别,只是因为我们不能直接利用Thread让这个线程运行起来,而是要通过一个中间
安卓中控制线程:
1、创建一个继承自View的类
2、定义一个Handler类对象handler,创建Callback的一个对象,重写其中的handleMessage方法,让它可以进行重绘,并传给handler。
3、重写onDraw方法
4、创建线程并启动
import java.util.ArrayList; import java.util.Random; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class DrawView extends View { private Bitmap bitmap; private Canvas canvas; private Paint paint = new Paint(); private ArrayList<Ball> list = new ArrayList<Ball>(); private Handler handler; public DrawView(Context context) { this(context, null); } public DrawView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DrawView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // 实例化handler handler = new Handler(callback); // 创建并启动线程 Thread t = new Thread(r); t.start(); } // 重写onDraw方法 public void onDraw(Canvas canvas) { // 实例化bitmap和canvas if (bitmap == null) { bitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Config.ARGB_8888); this.canvas = new Canvas(bitmap); canvas.drawColor(Color.RED); } // 循环遍历画出小球 for (int i = 0; i < list.size(); i++) { Ball ball = list.get(i); ball.move(); ball.draw(canvas); } canvas.drawBitmap(bitmap, 0, 0, paint); } public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: float x = event.getX(), y = event.getY(); // 随机x和y,vx,vy Random r = new Random(); float vx = 1 + r.nextInt(3), vy = 1 + r.nextInt(3); // 新增一个ball Ball ball = new Ball(x, y, vx, vy); list.add(ball); break; } return true; } public Callback callback = new Callback() { public boolean handleMessage(Message msg) { invalidate(); return false; } }; public Runnable r = new Runnable() { public void run() { while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } handler.sendEmptyMessage(0); } } }; }
但是当我们启动线程的时候,我们可能需要读取很多数据,比如图片,如果我们在线程里面再去提取我们所需要的图片的话,这个线程会变得相当卡。我们在玩游戏的时候,经常会发现游戏会出现“游戏正在加载中”这样的进度条,这就是在进行数据加载的工作,先把我们所需要的数据先读取到内存中,我们在线程中只需要调用就可以了。这个时候我们需要一个继承自Application的类,来实现我们加载数据的方法loa()。同时,我们还需要在AndroidManifest中把Application中的Name设置为MyApplication。
我们这时候讲到计时器的实现方法,其实代码很简单,我们只需要实例化一个Timer类的对象,实例化TimerTask的对象并实现抽象方法。
// 计时器 Timer timer = new Timer(); TimerTask task = new TimerTask() { public void run() { application.getList().add(new Ball(0, 0, 1, 1)); } }; timer.schedule(task, 1000, 5000);//每5秒进行一次任务
下面还是上代码:
//Ball类 import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; public class Ball extends Entity { private float x, y, vx, vy; private Paint paint = new Paint(); public Ball(float x, float y, float vx, float vy) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; } public void draw(Canvas canvas) { // Bitmap bitmap = MyApplication. /* * // 保存旋转之前的状态 * * canvas.save(); canvas.rotate(4, 40, 40); * * // 还原状态 canvas.restore(); */ Bitmap bitmap = MyApplication.getInstance().getBitmap("first"); canvas.drawBitmap(bitmap, x, y, paint); } public void move() { x += vx; y += vy; } }
import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.app.Application; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class MyApplication extends Application { public ArrayList<Entity> list = new ArrayList<Entity>(); private HashMap<String, Bitmap> maps = new HashMap<String, Bitmap>(); private static MyApplication instance; public MyApplication() { super(); instance = this; } public static MyApplication getInstance() { return instance; } public List<Entity> getList() { return list; } public void load(Context context) { try { Bitmap img = BitmapFactory.decodeStream(context.getResources() .getAssets().open("first.jpg")); maps.put("first", img); img = BitmapFactory.decodeStream(context.getResources().getAssets() .open("second.jpg")); maps.put("second", img); } catch (IOException e) { e.printStackTrace(); } } // 得到我们需要的图片的缓冲图的方法 public Bitmap getBitmap(String string) { return maps.get(string); } }
import java.util.List; import java.util.Timer; import java.util.TimerTask; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements Callback, Runnable { private SurfaceHolder holder; private MyApplication application; public MySurfaceView(Context context) { this(context, null); } public MySurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MySurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); holder = this.getHolder(); // holder.addCallback(this); // 添加回调接口 application = (MyApplication) context.getApplicationContext(); application.load(context); application.getList().add(new Ball(100, 100, 1, 1)); // 计时器 Timer timer = new Timer(); TimerTask task = new TimerTask() { public void run() { application.getList().add(new Ball(0, 0, 1, 1)); } }; timer.schedule(task, 1000, 5000);// 每5秒进行一次任务 } public void surfaceCreated(SurfaceHolder holder) { // 在创建的时候的时候启动线程 Thread t = new Thread(this); t.start(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceDestroyed(SurfaceHolder holder) { } public void run() { while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Canvas canvas = null; try { // 得到画布对象 canvas = holder.lockCanvas(); canvas.drawColor(Color.BLACK); List<Entity> list = application.getList(); for (int i = 0; i < list.size(); i++) { Entity e = list.get(i); e.draw(canvas); e.move(); } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) holder.unlockCanvasAndPost(canvas); } } } }
相关推荐
NULL 博文链接:https://chimer.iteye.com/blog/1040731
首先说明Android的CPU分配的最小单元是线程,Handler一般是在某个线程里创建的,因而Handler和Thread就是相互绑定的,一一对应。 而Runnable是一个接口,Thread是Runnable的子类。所以说,他俩都算一个进程。 ...
总结,结束Android线程时,关键在于优雅、安全地中断操作,而不是简单粗暴地停止。合理的线程管理可以提升用户体验,避免ANR,并保持应用程序的稳定运行。正确使用Thread、AsyncTask、Handler和Looper等工具,结合...
总结,理解和掌握Android线程管理是提升应用性能的关键。通过合理使用不同类型的线程和同步机制,开发者可以构建出既高效又稳定的Android应用程序。在实际项目中,根据任务特性和需求选择合适的线程模型,能显著提高...
### Java/Android线程使用深度解析 在计算机科学领域,线程与进程是核心概念,尤其是在多任务操作系统中。本文将深入探讨Java/Android环境下的线程管理,包括线程的创建、线程池的利用及`ThreadHandler`的运用等...
总结,这个资源包为Android开发者提供了全面的多线程编程知识,包括理论讲解、实战技巧以及辅助工具,是提升Android应用性能和响应性的重要参考资料。学习并掌握这些内容,将有助于开发者编写出更加高效、流畅的应用...
首先,理解Android线程模型至关重要。Android应用的主要工作线程被称为UI线程或主线程,它负责处理用户界面的更新和事件响应。后台线程通常用于执行耗时任务,避免阻塞UI线程。为了在后台线程和主线程之间交换数据和...
### 安卓线程间函数调用 #### 知识点概述 在Android开发中,线程间的函数调用是一个非常重要的概念。由于Android应用程序运行在一个事件驱动的环境中,因此通常需要在不同的线程之间传递数据或触发某些操作。本文...
### 安卓线程间函数调用和保存数值 #### 一、理解安卓中的线程间函数调用 在Android开发中,线程间的通信是非常重要的一个环节,尤其是在UI线程和其他工作线程之间的交互。因为Android为了保证用户体验,不允许在...
总结来说,Android的线程消息机制是通过Handler、Looper和Message Queue协同工作,实现线程间的通信和任务调度。它允许开发者在后台线程执行耗时操作,同时保持主线程的响应性,是构建高性能Android应用不可或缺的一...
总结来说,Android多线程的掌握对于开发者优化应用性能和提升用户体验至关重要。通过分析这个详细的demo,学生们可以逐步了解并掌握多线程的相关概念和技术,为日后的Android开发打下坚实的基础。在实际编程过程中,...
android开发中常用的线程通信,消息发送和接收,消息处理及定时器的使用
总结来说,Android中的多线程下载涉及到网络通信、线程管理、文件操作等多个方面,通过合理的代码设计和优化,可以显著提高下载效率,提供更好的用户体验。通过阅读提供的博客文章和分析`DownloadTest`代码,开发者...
### Android多线程机制详解 #### 一、引言 Android多线程机制是Android开发中非常重要的一部分,尤其是在处理耗时任务(如网络请求、大数据处理等)时,避免阻塞UI线程,保证应用程序的流畅性和响应性。本文将详细...
在Android平台上进行多线程下载是一项常见的任务,它涉及到网络编程、线程管理以及资源优化等多个方面的技术。本文将深入探讨Android多线程下载的核心知识点,帮助开发者更好地理解和实现这一功能。 1. **多线程...
总结,Android线程通信是优化应用性能、提升用户体验的关键技术。理解和熟练掌握各种通信机制,能够帮助开发者编写出更加高效、稳定的Android应用。通过实践Demo,可以加深对理论知识的理解,提高实际开发能力。
由于Android系统的安全机制,直接在子线程中修改UI是不允许的,因此我们需要通过特定的方式来实现子线程与UI线程之间的通信,以便在子线程完成任务后,能够安全地更新UI。`AndroidUIUpDemo`这个项目应该是一个展示...