Android 非守护线程的问题
《》我们知道在Android和Java一样,都可以使用非守护线程,那么现在提出这样一个问题:
现在我们在一个Activity类中开辟了一条非守护线程,这条非守护线程的任务是在一段时间之后改变一下Activity中某个组件的text,但是
如果我们在这条非守护线程执行完毕之前,就将Activity退出了,即主线程被强制退出,那么就出现了一个问题:那条非守护线程还得继续执行
,但是当执行到最后的时候需要把更改的信息传递给主线程的那个组件(可通过Handler),而现在主线程已经被强制退出了?那么这会不会出现问题呢?
《》验证上面的问题:我们模拟上面的情况,创建一个Activity类,加载一个布局文件,这个布局文件非常的简单,只有一个用来开辟新线程的按钮,和一个TextView
当我们但就这个按钮的时候,就会通过Timer开辟一条新的线程,这条新的线程会在5s钟之后,通过Handler传递一条信息告诉Activity主线程将TextView中的内容更改一下
(注意,我们应该记得,之前介绍过Timer开辟的线程默认是非守护线程)
代码如下:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button button = (Button) findViewById(R.id.button) ; final TextView textView = (TextView) findViewById(R.id.textView) ; final Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { if(msg.what == 0x123) { textView.setText("不知道现在怎么样了?"); Log.d("Tag","时间到了") ; } } } ; button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Timer().schedule(new TimerTask() { @Override public void run() { myHandler.sendEmptyMessage(0x123); } },5000); } }); } }
好了,现在我们执行下面的两种情况:
①我们调试运行该程序,但是单击按钮之后,就马上单击手机上的“HOME”键(按手机上的“HOME”键,并不会将程序退出,只是将程序转入后台),
结果是,再点击“HOME”5s钟之后,在DDMS的Log窗口中输出了“时间到了”,之后当我们再打开这个程序的时候,发现TextView中的文本已经变成了“不知道现在怎么样了?”
②我们调试运行该程序,但是单击按钮之后,就马上单击手机上的“返回”键(按手机上的“返回”键,会使程序强制退出),
结果是,再点击“返回”5s钟之后,在DDMS的Log窗口中依然输出了“时间到了”,之后程序也没有崩溃,当我们再在桌面上单击这个程序的磁贴后,又会出现一个没有任何更改的
全新的初始化程序
《》总结,实际上上面的情况非常的清楚:
对于非守护线程来说,即使主线程退出了,它还是要继续执行完毕,通过②情况中依然输出“时间到了”可以知道
其次,如果主线程在另一条非守护线程之前退出,那么这条非守护线程对主线程中的组件的更改是无效的,也即是说,那条非守护线程传给主线程的更改信息会被抛弃
但是,需要非常清楚的一点是:手机自然不能够和电脑相比,Dalvik虚拟机在非守护线程方面存在一定的弱化,当Dalvik虚拟机在执行其他的急需内存的情况下,那么它会优先将没有和任何可操作组件挂钩的线程给终止掉,这是一种强制性的所以最好避免这种 “完全隐藏的线程”的使用

浙公网安备 33010602011771号