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 个移动平 ...
随机推荐
- batchInsert xml 配置 ibatis
<insert id="tops_visa_openapi_jvisaproduct.batchinsert" parameterClass="java.util. ...
- ROS语音交互(四)接入图灵语义理解
首先程序中会用到Json,curl 安装相应的库 $ sudo apt-get install libcurl3 libcurl4-openssl-dev$ sudo apt-get install ...
- Tomcat容器虚拟路径设置
1.[官方文档]在tomcat\conf下server.xml中找到 <Host name="localhost" appBase="webapps" u ...
- 制造行业流程管理的“IPO”思维
流程管理是企业从流程角度出发,关注流程是否增值的一套管理体系.从认识流程.到建立流程.到管理流程.再到优化流程,企业管理人员要去除不增值和低价值的流程,减少员工犯错误的机会,建立一套卓越的流程体系. ...
- Android Build System
归类一些Android build system 相关的知识. http://elinux.org/Android_Build_System make <local_module> - m ...
- SpringMVC与MyBatis整合之日期格式转换
在上一篇博客<SpringMVC与MyBatis整合(一)——查询人员列表>中遗留了日期格式转换的问题,在这篇记录解决过程. 对于controller形参中pojo对象,如果属性中有日期类 ...
- 搬运:Python for Windows——监控Windows某个目录下文件的变化
https://win32com.goermezer.de/content/view/286/285/ 这个网站真是给力,不多说,代码直接搬运过来,还有我的测试结果,拿走不谢! import os i ...
- MiniTwitter记住密码等功能实现
一.SharedPreferences的用法:(相关实现功能的只是了解) 由于SharedPreferences是一个接口,而且在这个接口里没有提供写入数据和读取数据的能力.但它是通过其Editor接 ...
- Dapper学习笔记(3)-增、删、改、查
一.建表 在数据库中建立如下三张表: CREATE TABLE [dbo].[T_User] ( , ) PRIMARY KEY NOT NULL, ) NOT NULL, ) NULL, ) NUL ...
- Bootstrap-datetimepicker年月日
<div class="input-group date form_date" data-date="" data-date-format="y ...