Android笔记(三十一) Android中的异步更新(三) Handler (二)

先看简单示例:点击按钮,2s之后,TextView改变内容。

package cn.lixyz.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

/**
 * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。
 */

public class MainActivity extends Activity {

    private TextView textView;
    private Button button;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
        button = (Button) findViewById(R.id.button);

        handler = new MyHandler();

        button.setOnClickListener(new MyOnClickListener());
    }

    class MyOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            Thread t = new MyThread();
            t.start();
        }
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(2 * 1000);
                Message message = handler.obtainMessage();
                message.obj = "更改后的内容";
                handler.sendMessage(message);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String str = (String) msg.obj;
            textView.setText(str);
        }
    }
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="30dp"
        android:text="原来的内容"
        android:textSize="30dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:text="BUTTON" />

</LinearLayout>

activity_main.xml

运行结果:

通过Handler实现线程间通信

解释一下上面的代码:

1. 在onCreate中创建自定义的Handler对象

2. 设置按钮的点击监听事件,点击按钮之后,会启动一个线程

3. 线程启动之后,会先休眠2s,然后Handler对象会获取一个Message,设置Message的obj属性为“更改后的内容”,然后将Message发送出去

4. 在我们自定义的Handler类中,实现了handleMessage方法,在这个方法中,我们接收到message,然后将message中的obj取出,更新TextView。

再一个例子:

package cn.lixyz.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
 * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。
 */

public class MainActivity extends Activity {

    private EditText editText;
    private Button button;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        button = (Button) findViewById(R.id.button);

        handler = new MyHandler();

        button.setOnClickListener(new MyOnClickListener());
    }

    class MyOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            Thread t = new MyThread();
            t.start();
        }
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(2 * 1000);

                String str = editText.getText().toString();
                Message message = handler.obtainMessage();
                message.obj = str;
                handler.sendMessage(message);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String str = (String) msg.obj;
            Log.d("TTTT", "接收到的消息是" + str);
        }
    }
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:hint="输入要传送的内容"
        android:padding="30dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:text="BUTTON" />

</LinearLayout>

activity_main.xml

运行结果:

在子线程中发送,在主线程中接收,在子线程中处理,在主线程中更新

再稍微处理一下上面的代码,我们看一下他们的线程名:

package cn.lixyz.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
 * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。
 */

public class MainActivity extends Activity {

    private TextView textView;
    private Button button;
    private Handler handler;
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
        button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.editText);

        handler = new MyHandler();

        button.setOnClickListener(new MyOnClickListener());
    }

    class MyOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            Thread t = new MyThread();
            t.start();
        }
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(2 * 1000);
                String str = "****" + editText.getText().toString() + "****";
                Message message = handler.obtainMessage();
                message.obj = str;
                handler.sendMessage(message);
                Log.d("TTTT", "这里是发送消息的线程,发送的内容是:" + str + "  线程名是:" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String str = (String) msg.obj;
            textView.setText(str);
            Log.d("TTTT", "这里是更改UI的线程,接收到的内容是:" + str + "  线程名是:" + Thread.currentThread().getName());
        }
    }
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="30dp"
        android:text="原来的内容"
        android:textSize="30dp" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入要改变的文字" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:text="Send" />

</LinearLayout>

activity_main.xml

运行结果:

从运行结果我们可以看到,发送消息的线程是一个WorkerThread,更新UI的线程是一个MainThread,这样就解决了主线程和子线程之间的通信问题,我们可以在子线程中将数据处理完成之后回传给UI线程,让UI线程去更新UI组件。

时间: 2024-11-29 01:22:59

Android笔记(三十一) Android中的异步更新(三) Handler (二)的相关文章

Android笔记(五):Android中的Radio

原文地址:http://irving-wei.iteye.com/blog/1076097 上篇介绍了CheckBox,这节,将接触到的是RadioGroup和RadioButton. 它们的关系是:一个RadioGroup对应多个RadioButton,而一个RadioGroup中的RadioButton只能同时有一个被选中,它的选中值就是该RadioGroup的选中值. 这一节的代码运行效果图如下所示: 具体的代码编写过程如下: 首先在strings.xml中添加本程序所要用到的字符串: X

我的Android笔记(十一)——使用Preference保存设置

Android中有四种持久化数据的方法:SQLite数据库.文件存储.Preference.ContentProvider. 四种方法各有专攻,而其中Preference是以类似Map的键值对形式存储的,最适合用来保存用户个人设置之类的信息. 可以用一个xml文件来配置一个设置界面,然后用专门的PreferenceActivity将其显示.PreferenceActivity是专业的设置界面,只要给它指定一个配置好的xml,它就能自动根据操作更改程序Preference的相应值. 比如在res目

Oracle笔记(十一) 建表、更新、查询综合练习

Oracle笔记(十一) 建表.更新.查询综合练习 有某个学生运动会比赛信息的数据库,保存了如下的表: 运动员sporter(运动员编号sporterid,运动员姓名name,运动员性别sex,所属系号department) 项目item(项目编号itemid,项目名称itemname,项目比赛地点location) 成绩grade(运动员编号id,项目编号itemid,积分mark) 请用SQL语句完成如下功能: 1.  建表,并在相应字段上增加约束: 定义各个表的主键和外键约束: 运动员的姓

Android笔记(三十) Android中的异步更新(二) Handler

什么是Handler 之前说过了,Android不允许主线程(MainThread)外的线程(WorkerThread)去修改UI组件,但是又不能把所有的更新UI的操作都放在主线程中去(会造成ANR),那么只能单独启动一个子线程(WorkerThread)去处理,处理完成之后,将结果通知给UI主线程,子线程和主线程的通信就用到了Handler. Handler.Looper和MessageQueue的基本原理 先看一下他们的职责: Handler——处理者,负责发送以及处理Message. Me

Android笔记(十一) Android中的布局——AndroidManiFest.xml

AndroidManiFest.xml清单文件是每个Android项目所必须的,它是整个Android应用的全局描述文件.AndroidManiFest.xml清单文件说明了该应用的名称.所使用的图标以及包含的组件等等. AndroidManiFest.xml清单文件通常包含如下信息: 1. 应用程序的包名,该包名将会作为该应用的唯一标识 2. 应用所包含的组件,如Activity.Service.BroadcastReceiver和ContentProvider等 3. 应用程序兼容的最低版本

Android笔记(十一)第一个Fragment

Fragment是碎片的意思,能够參照Activity来理解Fragment,由于它们都能包括布局,都有自己的生命周期. 以下我们要让主活动包括两个碎片,而且让两个碎片充满屏幕 1.首先,新建两个碎片的布局文件 left.xml <?xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/an

Android笔记(六十三) android中的动画——逐帧动画( frame-by-frame animation)

就好像演电影一样,播放实现准备好的图片,来实现动画效果. 逐帧动画需要用到AnimationDrawable类,该类主要用于创建一个逐帧动画,然后我们把这个动画设置为view的背景即可. android提供两种方法为AnimationDrawable添加帧:XML定义和JAVA代码创建. XML 因为动画帧的资源需要是一个Drawable对象,所以需要把它放到Drawable目录下.在<animation-list>使用<item>来添加一帧 anima.xml <?xml

android笔记5——同一个Activity中Fragment的切换

今天来模拟一个注冊的界面过程: 点击"下一步"之后: 说明一下:界面总局仅仅在一个Activity里面. 1.首先定义RegistActivity public class RegistActivity extends Activity { private EditText userEditText; private EditText verifyCodeText; private Fragment verifyCodeFragment; private Fragment checkC

EF6基础系列(十一)---EF6中的异步查询和异步保存

EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法实现异步查询的栗子: private static async Task<Student> GetStudent() { Student student = null; using (var context = new SchoolDBEntities()) { Console.WriteLine