android操作线程各种方法解析
(一)刚开始学习android的时候我是这么写的
new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start();
后来看到别的博客说这种违反android单线程模型 本人不理解非要刨根问题
那么它是怎么违反单线程模型的呢?
百度了一下找到了原因 如下
一个 Android 程序开始运行时,就有一个主线程Main Thread被创建。该线程主要负责UI界面的显示、更新和控件交互,所以又叫UI Thread。由于只有UI线程更新界面所以说
Android是单线程模型。 一个Android程序创建之初,一个Process呈现的是单线程模型--即Main Thread,在非主线程(UI线程)外调invalidate()刷新界面出现异常,即是说用其他的线程更新UI,android中是不被允许的
例如:在非UI线程中调用invalidate会导致线程不安全,也就是说可能在非UI线程中刷新界面的时候,UI线程(或者其他非UI线程)也在刷新界面,这样就导致多个界面刷新的操作不能同步,导致线程不安全
哦 那我明白了 如果这样写呢 涉及到多个非UI线程操作UI 会引起冲突 所以不建议这样写 但也不能一竿子打死吧 如果我这样写 不涉及到UI操作 例如我只是做http操作 获取数据库数据
也会导致线程不安全嘛? 我个人觉得只要不涉及到UI操作 这样写也可以 所以android还是支持的
(二)Thread+Handler
发觉常用的方法是利用Handler来实现UI线程的更新的 大家都这么写
我通常是这样写 自定义一个handler 和 Runnable 方便以后扩展
/**
* 自定义Handler
*
* @author 龙塔
*
*/
public abstract class MyHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
try
{
myHandleMessage(msg);
}
catch (Exception e)
{
e.printStackTrace();
}
} protected abstract void myHandleMessage(Message msg) throws Exception;
}
/**
* 自定义Runnable
*
* @author 龙塔
*/
public abstract class MyRunnable implements Runnable
{
@Override
public void run()
{
try
{
myRun();
}
catch (Exception e)
{
e.printStackTrace();
}
} protected abstract void myRun() throws Exception;
}
final MyHandler handler = new MyHandler()
{
@Override
protected void myHandleMessage(Message msg) throws Exception
{
}
};
new Thread(new MyRunnable()
{
@Override
protected void myRun() throws Exception
{
Looper.prepare();
dynamicTable = new DynamicTable(testActivity.this);
Message message = handler.obtainMessage();
//测试方法
message.obj = dynamicTable .loadTable(questionnaire);
message.sendToTarget();
Looper.loop();
}
}).start();
}
Handler来根据接收的消息,处理UI更新。Thread线程发出Handler消息,通知更新UI 参见了各种文档和api demo发现都是这样调用的
这样调用应该万无一失了吧 呵呵
(三)java习惯。Android平台中,这样做是不行的,这跟Android的线程安全有关 又是涉及到UI操作的 如果不是操作UI 这种方法我觉得可以用的
在Android平台中需要反复按周期执行方法可以使用Java上自带的TimerTask类,TimerTask相对于Thread来说对于资源消耗的更低,除了使用Android自带的AlarmManager使用Timer定时器是一种更好的解决方法。 我们需要引入import java.util.Timer; 和 import java.util.TimerTask;
public class JavaTimer extends Activity { Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run() {
setTitle("hear me?");
}
}; public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); timer.schedule(task, 10000); }
}
方法四:(TimerTask + Handler) 方法3的升级版
错误写法 涉及到线程安全
public class TestTimer extends Activity { Timer timer = new Timer();
Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
setTitle("hear me?");
break;
}
super.handleMessage(msg);
} }; TimerTask task = new TimerTask(){
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}; public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); timer.schedule(task, 10000);
}
}
正确写法 交由UI Thread处理
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
public class TestTimer extends Activity {
Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run() { runOnUiThread(new Runnable(){
@Override
public void run() {
setTitle("hear me?");
}});
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timer.schedule(task, 10000);
}
}
正确写法二 :由Handler处理UI 更新。
package com.test; import java.util.Timer;
import java.util.TimerTask; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message; public class TestTimer extends Activity { Timer timer = new Timer();
Handler handler = new Handler(){ public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
setTitle("hear me?");
break;
}
super.handleMessage(msg);
} };
TimerTask task = new TimerTask(){ public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
} };
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timer.schedule(task, 10000);
}
}
在Android中还提供了一种有别于线程的处理方式,就是Task以及AsyncTask
具体用法可以参见这个帖子
http://blog.csdn.net/liuhe688/article/details/6532519
android操作线程各种方法解析的更多相关文章
- PHP XML操作的各种方法解析
PHP提供了一整套的读取 XML文件的方法,很容易的就可以编写基于 XML的脚本程序.本章将要介绍 PHP与 XML的操作方法,并对几个常用的 XML类库做一些简要介绍. XML是一种流行的半结构化文 ...
- Android终止线程的方法
线程对象属于一次性消耗品,一般线程执行完run方法之后,线程就正常结束了,线程结束之后就报废了,不能再次start,只能新建一个线程对象.但有时run方法是永远不会结束的.例如在程序中使用线程进行So ...
- java创建线程的方法
1.1 创建线程 1.1.1 无返回值的线程创建 package com.first; public class ThreadTest { public static void ma ...
- Android子线程更新UI的方法总结
版权声明:本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=6121280 消息机制,对于Android开发者来说,应该是非常 ...
- 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析
作者 : 韩曙亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 ...
- Android多线程编程<一>Android中启动子线程的方法
我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改 ...
- Android 子线程 UI 操作真的不可以?
作者:vivo 互联网大前端团队- Zhang Xichen 一.背景及问题 某 SDK 有 PopupWindow 弹窗及动效,由于业务场景要求,对于 App 而言,SDK 的弹窗弹出时机具有随机性 ...
- Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个 ...
- PhoneGap 在 Android 上的插件开发方法介绍
移动应用开发已经成为软件开发的一个重要方向,但是移动开发面临的一个重要问题就是跨平台的问题.PhoneGap 作为一个多平台的软件开发框架,提供了一次编写多个平台的运行.目前已经支持多达 6 个移动平 ...
随机推荐
- 安装CAD2006装好了为什么不能用,显示系统错误无法启动此程序,因计算机丢失aclst.dll。尝试重新安装该程序以解
我的电脑,右键 属性——>高级选项卡(win7的是高级系统设置)——>环境变量——>系统变量——>然后新建系统变量 变量名为:AutoCAD 变量值为:c:\program f ...
- 揭秘JavaScript中谜一样的this
揭秘JavaScript中谜一样的this 在这篇文章里我想阐明JavaScript中的this,希望对你理解this的工作机制有一些帮助.作为JavaScript程序员学习this对于你的发展有 ...
- Android6.0中的权限
Android6.0相比之前的Android版本有一个很大的不同点,就是动态的获取权限.之前我们需要什么权限只需要在Manifest文件中声明即可,在6.0中,又新增了运行时权限的动态检测. Andr ...
- 对copy、mutableCopy理解
Objective - C 中有很多在日常项目中经常用到的常用代码,在这里着重的讲一下关于copy 和 mutableCopy 的区别以及相关用法. Objective - C 中可变对象和不可对象经 ...
- 用markdown学习写出总结
# PS### 快捷键:CTRL+N(新建)CTRL+1. **切片**- 套索,磁性套索,椭圆,矩形选框.2. **印章** 仿制图章工具,图案图章工具3. 钢笔4. 油漆桶5. 吸管工具, *** ...
- Eclipse+Maven创建webapp项目
Eclipse+Maven创建webapp项目<一> 1.开启eclipse,右键new-->other,如下图找到maven project 2.选择maven project,显 ...
- Bootstrap<基础十三> 按钮组
按钮组允许多个按钮被堆叠在同一行上.当你想要把按钮对齐在一起时,这就显得非常有用.你可以通过Bootstrap 按钮(Button) 插件 添加可选的 JavaScript 单选框和复选框样式行为. ...
- java字符串大小写字母互改
import java.util.Scanner; public class Test { /** * 测试数据 * * @param args */ public static void main( ...
- 讨论SEO中是锚文本有效,还是纯文本有效呢?
现在很多SEO好友不断在讨论,在SEO优化中,到底是锚文本有效,还是纯文本有效呢? 在这里给大家举一下列子:如“张家口人才网”这样的就叫做锚文本,意思是在原有的文本中加上超级链接,指向到优化的网页上面 ...
- linux下如何使用sftp命令
sftp 是一个交互式文件传输程式.它类似于 ftp, 但它进行加密传输,比FTP有更高的安全性.下边就简单介绍一下如何远程连接主机,进行文件的上传和下载,以及一些相关操作. 举例,如远程主机的 IP ...