(一)刚开始学习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操作线程各种方法解析的更多相关文章

  1. PHP XML操作的各种方法解析

    PHP提供了一整套的读取 XML文件的方法,很容易的就可以编写基于 XML的脚本程序.本章将要介绍 PHP与 XML的操作方法,并对几个常用的 XML类库做一些简要介绍. XML是一种流行的半结构化文 ...

  2. Android终止线程的方法

    线程对象属于一次性消耗品,一般线程执行完run方法之后,线程就正常结束了,线程结束之后就报废了,不能再次start,只能新建一个线程对象.但有时run方法是永远不会结束的.例如在程序中使用线程进行So ...

  3. java创建线程的方法

    1.1      创建线程 1.1.1     无返回值的线程创建 package com.first; public class ThreadTest { public static void ma ...

  4. Android子线程更新UI的方法总结

    版权声明:本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=6121280 消息机制,对于Android开发者来说,应该是非常 ...

  5. 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析

    作者 : 韩曙亮 转载请著名出处 :  http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 ...

  6. Android多线程编程<一>Android中启动子线程的方法

          我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改 ...

  7. Android 子线程 UI 操作真的不可以?

    作者:vivo 互联网大前端团队- Zhang Xichen 一.背景及问题 某 SDK 有 PopupWindow 弹窗及动效,由于业务场景要求,对于 App 而言,SDK 的弹窗弹出时机具有随机性 ...

  8. Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个 ...

  9. PhoneGap 在 Android 上的插件开发方法介绍

    移动应用开发已经成为软件开发的一个重要方向,但是移动开发面临的一个重要问题就是跨平台的问题.PhoneGap 作为一个多平台的软件开发框架,提供了一次编写多个平台的运行.目前已经支持多达 6 个移动平 ...

随机推荐

  1. nmon--非常棒的LINUX/AIX性能计数器监测和分析工具

    转自51Testinghttp://bbs.51testing.com/viewthread.php?tid=116526 经常看到很多人讨论说loadrunner对linux/aix的性能监测太少, ...

  2. ubtuntu 下安装Erlang R17

    在Ubuntu 下 Erlang R17B 的安装的过程记录: 1 :如果你主机上没有安装jdk,那需先安装,安装过程如下:   #   sudo apt-get update (更新已安装的包)   ...

  3. <java基础学习>02JAVA的基础组成(2)

    60000-0000 0000-0000 0000-0000 0000-0110 0000-0110 -6这个数的正数的二进制取反,再加1 0000-0110取反: 1111-1001 + 0000- ...

  4. 【JavaScript】放大镜效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. web开发流程(传智播客-方立勋老师)

    1.搭建开发环境 1.1 导入项目所需的开发包 dom4j-1.6.1.jar jaxen-1.1-beta-6.jar commons-beanutils-1.8.0.jar commons-log ...

  6. Linux 文件的基本操作

    1>.新建空白文件: touch命令-->$ touch test 2>.新建目录: mkdir命令-->$mkdir mydir 使用 -p参数:同时创建父目录-->$ ...

  7. 例子:Bluetooth app to device sample

    本例子演示了: 判断蓝牙是否打开,是通过一个HRsult值为0x8007048F的异常来判断的 catch (Exception ex) { if ((uint)ex.HResult == 0x800 ...

  8. 一个Java递归删除目录的方法

    public static void delDir(File f) { // 判断是否是一个目录, 不是的话跳过, 直接删除; 如果是一个目录, 先将其内容清空. if(f.isDirectory() ...

  9. 当你刷新当前Table时,刷新后如何回到你上一次所在位置呢?

    第一: 在你刷新前保存所在位置的行号 procedure XXXClass.LockPositionEx;begin DisableControls; FHistoryRecNo := 0; FHis ...

  10. 几款Z2760平板对比

    现阶段的Windows平板本质上分为Windows RT系统平板和完整的Windows 8系统平板两大阵营.RT系统的平板轻薄续航持久,但是由于没法安装常规的.exe程序,所以对于工作需要略显不足,是 ...