android开发问题。。关于handler的sendmessage

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android开发问题。。关于handler的sendmessage相关的知识,希望对你有一定的参考价值。

class MyButtonListener3 implements android.view.View.OnClickListener @Override public void onClick(View v) // TODO Auto-generated method stub updataBarHandler.post(updataThread); ; Handler updataBarHandler = new Handler() @Override public void handleMessage(Message mag) // TODO Auto-generated method stub Bar01.setProgress(mag.arg1); updataBarHandler.post(updataThread); ; Runnable updataThread = new Runnable() int i = 0; @Override public void run() // TODO Auto-generated method stub i = i + 1; Message mag = updataBarHandler.obtainMessage(); mag.arg1 = i; try Thread.sleep(100); catch (InterruptedException e) // TODO Auto-generated catch block e.printStackTrace(); updataBarHandler.sendMessage(mag); if(i==100) updataBarHandler.removeCallbacks(updataThread); ;
是这么一段代码。。我想知道详细的运行步骤。
是不是每一次执行 updataThread 都会跳出来,然后得到一个mag?这样的话为什么程序还能回到 handleMessage(Message mag)里面,难道java是并行式的?每一次执行难道不会重置 int i = 0;吗?只运行run的部分?
当i==100时,还是会发一次message,然后才执行updataBarHandler.removeCallbacks(updataThread);可是按照处理顺序,handleMessage(Message mag)还是会再次处理mag,然后再次启动进程,为什么进程停止了?
垃圾知道。。。空格全没了

参考技术A 此代码是创建新线程,执行run方法后,在发送消息到handler,有handlerMessage()回调方法处理,你线程中无循环,怎么会循环执行呢,以上请采纳本回答被提问者采纳 参考技术B 因为updateThread是一个匿名类的实例(只new了一次)。其数据成员(field) i的生命周期在不设置为null的情况下跟所在的父类(比如你的activity)一致,所以不会销毁。如果你每次post的时候都是new Runnable,不声明类成员变量,那么i就不会一直往上加。

Android开发学习之路--异步消息Handler,Message,Looper和AsyncTask之初体验

    在简易音乐播放器中,用了Handler,也没有过多地去研究学习,这里再学习下android下的异步消息处理机制。这里用了Handler主要是在线程中不能更新UI,而需要通过Handler才可以。关于异步消息处理有几个概念。

    1、Message:消息,线程间通讯的数据单元。例如后台要下载歌曲然后下载完成要更新ui,则可以发送一条包含更新信息的Message给UI线程。

    2、MessageQueue:消息队列,用来存放所有通过Handler发布的消息,因为是队列,所以是先进先出的。

    3、Handler:Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。

    4、Looper:循环管理MessageQueue,循环取出MessageQueue中的Message,并交给相应的Handler进行处理。

    5、线程:UI thread是main thread,android启动程序时会替他建立一个MessageQueue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。

     下面来个例子吧还是,新建工程HandlerTest,编写简单布局如下:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:layout_margin="10dp"
    tools:context="com.example.jared.handlertest.MainActivity">

    <EditText
        android:id="@+id/inputContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入要改变的内容"/>

    <Button
        android:id="@+id/changeViewContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Change The ViewContent"
        android:textAllCaps="false"/>

    <TextView
        android:id="@+id/testHandler"
        android:text="I am old!!!"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:textSize="22dip"
        android:layout_gravity="center"/>

</LinearLayout>

    这里输入内容,按button,改变TextView的内容。编写MainActivity代码如下:

package com.example.jared.handlertest;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final int UPDATA_VIEW = 1;

    private TextView textView;
    private Button changeContent;
    private EditText inputContent;

    private Thread  mThread;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATA_VIEW:
                    String mInputContent = inputContent.getText().toString();
                    textView.setText(mInputContent);
                    break;
                default:
                    break;
            }
        }
    };

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

        textView = (TextView)findViewById(R.id.testHandler);
        inputContent = (EditText)findViewById(R.id.inputContent);

        changeContent = (Button)findViewById(R.id.changeViewContent);
        changeContent.setOnClickListener(new myOnClickListener());
    }

    private class myOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.changeViewContent:
                    mThread = new Thread(runnable);
                    mThread.start();
                    break;
                default:
                    break;
            }
        }
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Message message = new Message();
            message.what = UPDATA_VIEW;
            mHandler.sendMessage(message);
        }
    };
}

    这里先new了一个Handler,handleMessage方法处理发送的Message,Thread里面发送message,然后更新TextView的内容,运行如下:

技术分享           技术分享

    基本的Handler已经完成了,下面再学习下AsyncTask。

    AsyncTask是方便编写后台线程和UI线程的辅助类。它内部的实现是一个线程池,每个后台会提交到线程池中去执行。AsyncTask有三个模板函数:

    1、Params:传递给后台任务的参数类型。

    2、Progress:后台计算执行过程中,进步的单位类型。

    3、Result:后台执行返回的结果的类型。

    当标示不需要的类型的时候,只要用Void就行了。

    AsyncTask需要重写5个方法,分别是:

    1、onPreExecute方法:准备运行,该回调函数在任务被执行之后立即由UI线程调用,一般可以显示进度条。

    2、doInBackground(Params ...)方法:正在后台运行,通常在这里执行耗时的后台计算,计算结果返回给函数,这里如果AsyncTask的第三个参数是Void的话不需要返回,这里不能更新UI,但是可以调用publishProgress(Progress ...)方法完成。

    3、onProgressUpdate(Progress ...)方法:进度更新,UI线程在publishProgress(Progress ...)方法调用完成后被调用,一般动态显示一个进度。

    4、onPostExecute(Result)方法:完成后台任务,会返回,这里可以进行些UI的操作,比如提醒任务执行的结果,以及关闭掉进度条对话框等。

    5、onCancelled方法:取消任务,在调用AsyncTask的cancel()方法的时候调用。

    下面通过AsyncTask的方式来进行上面的例子,Handler的代码就没有删除掉了,代码如下:

package com.example.jared.handlertest;

import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final int UPDATA_VIEW = 1;

    private TextView textView;
    private Button changeContent;
    private EditText inputContent;

    private Thread  mThread;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATA_VIEW:
                    String mInputContent = inputContent.getText().toString();
                    textView.setText(mInputContent);
                    break;
                default:
                    break;
            }
        }
    };

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

        textView = (TextView)findViewById(R.id.testHandler);
        inputContent = (EditText)findViewById(R.id.inputContent);

        changeContent = (Button)findViewById(R.id.changeViewContent);
        changeContent.setOnClickListener(new myOnClickListener());
    }

    private class myOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.changeViewContent:
                   // mThread = new Thread(runnable);
                   // mThread.start();
                    changeViewContentTask  task = new changeViewContentTask();
                    task.execute();
                    break;
                default:
                    break;
            }
        }
    }

    class changeViewContentTask extends AsyncTask<Void, Integer, Boolean> {
        @Override
        protected Boolean doInBackground(Void... voids) {
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
        }

        @Override
        protected void onPostExecute(Boolean b) {
            String mInputContent = inputContent.getText().toString();
            textView.setText(mInputContent);
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onCancelled() {
        }
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Message message = new Message();
            message.what = UPDATA_VIEW;
            mHandler.sendMessage(message);
        }
    };
}
    这里实例化一个task,然后task.execute();就可以执行了,效果如上就不添图了。





以上是关于android开发问题。。关于handler的sendmessage的主要内容,如果未能解决你的问题,请参考以下文章

Android开发:Handler异步通信机制全面解析(包含LooperMessage Queue

Android开发学习之路--异步消息Handler,Message,Looper和AsyncTask之初体验

Android开发学习之路--异步消息Handler,Message,Looper和AsyncTask之初体验

Android全面解析Handler

Android-Handler消息机制

关于Handler的理解,子线程不能更新UI的纠正和回调的思考