android中的线程
❶ android开发中线程有几种状态,分别是哪些
【答案】:1)、新建状态(New):新创建了一个线程对象。
2)、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3)、运行状态(Running):就绪状态的线程获取了CPU,执行run()方法。
4)、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5)、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
当调用start方法的时候,该线程就进入就绪状态。等待CPU进行调度执行,此时还没有真正执行线程。
当调用run方法的时候,是已经被CPU进行调度,执行线程的主要任务。
❷ Android:在一个非主线程内直接调用UI线程的Handler实例,这样没问题吗
在Android开发中,我们常常遇到线程安全的问题,特别是在子线程和UI线程之间进行交互时。为了保证应用程序的稳定性和用户体验,我们不能直接在子线程中更新UI线程中的UI元素。为了解决这个问题,Android提供了一种机制——Handler。
Handler的工作原理是这样的:当子线程需要更新UI线程中的UI元素时,它会通过发送消息的方式,将需要更新的内容传递给UI线程。这些消息会被放入UI线程的消息队列中,然后由UI线程中的Handler逐个处理。这样,我们就可以在子线程中执行耗时操作,同时在UI线程中更新UI,从而保证了界面的流畅性。
在Android中,创建多线程的方式主要有两种:一种是通过继承Thread类并重写run方法;另一种是通过实现Runnable接口并实现run方法。无论哪种方式,子线程都无法直接修改UI线程中的UI元素,而Handler正是用来解决这一问题的关键。
Handler的主要方法包括post、postAtTime、postDelayed、sendEmptyMessage、sendMessage、sendMessageAtTime、sendMessageDelayed等。这些方法分别用于在主线程中执行Runnable或发送消息。通过这些方法,我们可以灵活地控制消息的发送时机和执行方式。
下面,我们通过一个简单的例子来说明Handler的使用方法。假设我们需要在主线程中的TextView中显示10到100之间的随机数,每隔5秒更新一次,总共更新5次。主要代码如下:
java
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.post(run);
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
String s = String.valueOf(msg.what);
TextView tv = (TextView)findViewById(R.id.textView);
tv.setText(tv.getText() + " " + s);
}
};
Runnable run = new Runnable(){
@Override
public void run(){
Random r = new Random();
int rnum = r.nextInt((100 - 10) + 1) + 10;
handler.sendEmptyMessage(rnum);
handler.postDelayed(run, 5000);
i++;
if (i==5){
handler.removeCallbacks(run);
}
}
};
通过这个例子,我们可以看到Handler在处理子线程与UI线程之间的交互时的重要作用。在实际开发中,我们可以根据具体需求,灵活地使用Handler的各种方法来实现复杂的线程交互逻辑。