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 个移动平 ...
随机推荐
- 使用ASP.NET上传图片汇总
1 使用标准HTML来进行图片上传 前台代码: <body> <form id="form1" runat="server"> ...
- 【图像处理】【SEED-VPM】7.ubuntu10.04下 TFTP,NFS 安装指南
Linux系统启动流程 程序开发调试的一般方法 1. TFTP下载内核+NFS网络文件系统.即内核和文件系统均不在板卡上.主要用于调试内核功能. 2. FLASH启动内核+NFS网络文件系统,即内核固 ...
- 书旗小说app点评
书旗小说这个手机软件用了好久了,大一的时候就开始用,业余无聊时间可以看一看网络小说打发一下时间. 书旗免费小说是一款内容以免费小说书旗网为基础的在线阅读器,除了拥有传统阅读器的书籍同步阅读.全自动书签 ...
- win环境 yii2 框架 overtrue/wechat 包 由 sys_get_temp_dir 引发的 the directory "c:\Windows" is not writable
vendor\overtrue\wechat\src\Foundation\Application.php registerBase 方法 在初始化属性时 $this['cache'] = funct ...
- Java线程池使用说明
Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...
- 用PowerMock mock final类constructors
也相对简单,直接贴代码 被测方法 public class EmployeeServiceWithParam { public void createEmployee(final Employee e ...
- OpenCV中的矩阵操作
函数 Description 说明 cvAdd Elementwise addition of two arrays 两个数组对应元素的和 cvAddS Elementwise addition of ...
- web.config设置和取值
博客园中有一篇文章对web.config的结构做了很详细的介绍,原文见 http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.htm ...
- iOS---XMPP环境搭建过程
什么是即时通信? 即时通信是目前Internet上最为流行的通讯方式, 各种各样的即时通讯软件也层出不穷, 服务提供商也提供了越来越枫木的通讯服务功能. 即时通讯有多重实现方式, XMPP就是其中一种 ...
- asp.net MVC code first Migrations : Model 同步到DB中
找来找去,看来用这个功能的人很少. http://www.it165.net/pro/html/201403/10653.html 步骤: 1,在程序包管理控制台上,Enable-Migrations ...