android操作线程各种方法解析

(一)刚开始学习android的时候我是这么写的

1 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

  

时间: 2024-08-27 14:49:42

android操作线程各种方法解析的相关文章

Android Measure中对应方法解析

注:根据网上资料整理如下 首先 onMeasure方法是为了得到各个View大小的函数 fill_parent-->public static final int EXACTLY = 1 << MODE_SHIFT; wrap_content-->public static final int AT_MOST = 2 << MODE_SHIFT; 这是makeMeasureSpec方法的代码片段 public static int makeMeasureSpec(int

18.4 操作线程的方法

一.线程的休眠 一种控制线程行为的方法使调用sleep()方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位 sleep()方法的语法如下: try{ Thread.sleep(2000); }catch(InterruptedException e){ e.printStackTrace(); } 上述代码会使线程在2秒之内不会进入就绪状态.由于sleep()方法的执行有可能抛出InterruptedException异常,所以将sleep()方法的调用放在try

java创建线程的方法

1.1      创建线程 1.1.1     无返回值的线程创建 package com.first; public class ThreadTest { public static void main(String[] args)  { System.out.println("主线程ID:"+Thread.currentThread().getId()); MyThread thread1 = new MyThread("thread1");//(1)继承thr

java android ExecutorService 线程池解析

ExecutorService: 它也是一个接口,它扩展自Executor接口,Executor接口更像一个抽象的命令模式,仅有一个方法:execute(runnable);Executor接口简单,可是非常重要,重要在这样的设计的模式上..Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中,能够非常easy控制线程的启动.运行和关闭过程,还能够非常easy使用线程池的特性. 几种不同的ExecutorService线程池对象 1.newCachedT

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

作者 : 韩曙亮 转载请著名出处 :  http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 Android MediaPlayer 状态即图例 : 1. Idle (闲置) 状态 和 End (结束) 状态 MediaPlayer 对象声明周期 : 从 Idle 到 End 状态就是 MediaPlayer 整个生命周期; -- 生命周期開始 : 进入 Idle (闲置) 状态; -- 生

android子线程中更新UI的方法

在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 参考:Android子线程 方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: //

Android子线程更新UI主线程方法之Handler

背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. 下面说下有关Handler相关的知识. 多线程一些基础知识回顾:在介绍Handler类相关知识之前,我们先看看在Java中是如何创建多线程的方法有两种:通过继承Thread类,重写Run方法来实现通过继承接口Runnable实现多线程 具体两者的区别与实现,看看这篇文章中的介绍:http://de

Android关于线程更新UI的方法

Android关于线程更新UI的方法 在一个Android 程序开始运行的时候,会单独启动一个Process.默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process.   一个Android 程序默认情况下也只有一个Process,但一个Process下却可以有许多个Thread.   在

线程间操作无效: 从不是创建控件“控件id”的线程访问它。(.net跨线程执行方法)

找了好久资料,终于解决了,特此记录下来. 1 delegate void DelListHandler(string number); /// <summary> /// 按标识删除listview内容 /// </summary> /// <param name="number">标识</param> private void DelListViewLog(string number) { for (int i = 0; i <