Handler机制和AsyncTask机制的使用

来源:互联网 发布:宁波天使在线网络 编辑:程序博客网 时间:2024/06/03 15:54

参考自:http://blog.csdn.net/liuhe688/article/details/6532519


涉及的知识点:

1、Handler内存泄露问题的解决方法,使用弱引用的方式解决(http://blog.csdn.net/qq_28468727/article/details/52641501)

2、Handler的使用方式

3、线程的使用

4、异步消息的处理机制

5、AsyncTask的使用

6、使用HttpURLConnection获取网络数据(获取网络上的一个页面)

7、进度条的使用(在AsyncTask的使用实例中)

8、显示获取网络数据的进度

.

Android中实现异步任务机制的方式有两种方式:HandlerAsyncTask

一、异步消息处理机制

Android 异步消息处理主要由四个部分组成:MessageMessageQueueHandlerLooper

(1)Message

线程之间传递的消息,它在内部携带信息,用于不同线程之间交换数据。

(2)MessageQueue

消息队列,主要是用于存放Handler发送的消息,这些消息会一直存在于消息队列中等待处理。每个线程只有一个MessageQueue

(3)Handler

主要用于消息的发送和消息的处理。发送的消息一般是使用HandlersendMessage()方法,处理消息是使用Handler的方法handlerMessage()方法。

(4)Looper

是每个线程中MessageQueue的管家,调用Looper中的loop()方法之后,就会进入一个无线循环中,一发现MessageQueue中的消息,就会将其取出并将其传递到Handler中的handlerMessage方法中进行处理。

 

异步消息的整个处理流程:

当我们需要进行UI操作,我们将一个消息通过Handler的方法sendMessage将消息发送到MessageQueue中等待被处理,LooperMessageMessageQueue中取出并将其发送到HandlerhandlerMessage方法中,由于Handler的对象是在UI线程中创建的,因此就可以进行进行UI的操作了。

 

二、AsyncTask

AsyncTask的定义:

public abstract class AsyncTask<Params, Progress, Result> { 

AsyncTask是一个抽象类,我们需要自己定义一个子类去继承它,在继承的时候我们需要去指定三个泛型

(1)Params    AsyncTask执行时传入的参数

(2)Progress   后台任务执行的进度

(3)Result     后台执行的结果

 

异步任务执行的步骤:

(1)execute(Params),执行一个异步任务,我们在需要的代码中调用此方法,触发异步任务的执行

(2)onPreExecute(),在execute(Params)执行后被立即执行,用于界面上的一些初始化的操作

(3)doInBackgroundParams.....),在onPreExecute()后立即执行,用于费时的操作,在执行的过程中可以调用publishProgress(Progress....)来更新进度消息。

(4)onProgressUpdate(Progress... values),当调用publishProgress(Progress....)时,此方法被调用,直接将进度消息更新到UI组件上

(5)onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

 

使用AsyncTask需要注意的地方

(1)AsyncTask的实例必须在UI线程中创建

(2)execute方法必须在UI线程中进行调用

(3)不要手动调用onPreExecute()doInBackground()onProgressUpdate(Progress... values)onPostExecute(Result result)这几个方法

(4)不能再doInBackground方法中进行更改UI组件的操作

(5)一个任务实例只能执行一次,如果执行第二次将会抛出异常。

 


Handler机制使用实例

TestHandlerActivity.java

package com.example.administrator.learnaynctask;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.TextView;import org.w3c.dom.Text;import java.lang.ref.WeakReference;public class TestHandlerActivity extends AppCompatActivity {    private Button btn;    private TextView tv_show;    private MyHandler myhandler = new MyHandler(this);    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_test_handler);        tv_show = (TextView) findViewById(R.id.textView);        btn = (Button) findViewById(R.id.btn_start);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                MyThree myThree = new MyThree();                myThree.start();            }        });    }    public void updateUIThread(Message msg){        Bundle bundle = new Bundle();        bundle = msg.getData();        int i = bundle.getInt("result");        tv_show.setText(i+"");    }    public class MyThree extends Thread{        @Override        public void run() {            super.run();            int i =0;            while(i <= 30){                Bundle bundle = new Bundle();                bundle.putInt("result",i);                Message msg = new Message();                msg.setData(bundle);                myhandler.sendMessage(msg);                i++;                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }    //弱引用,防止内存泄露    private static class MyHandler extends Handler {        private final WeakReference<TestHandlerActivity> mActivity;        public MyHandler(TestHandlerActivity activity) {            mActivity = new WeakReference<TestHandlerActivity>(activity);        }        @Override        public void handleMessage(Message msg) {            System.out.println(msg);            if (mActivity.get() == null) {                return;            }            mActivity.get().updateUIThread(msg);        }    }}

效果图



AsyncTask机制使用实例

MainActivity.java

package com.example.administrator.learnaynctask;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity {    private static final String TAG = "ASYNC_TASK";    private Button execute;    private Button cancel;    private ProgressBar progressBar;    private TextView textView;    private MyTask mTask;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        execute = (Button) findViewById(R.id.execute);        execute.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常                mTask = new MyTask();                mTask.execute("http://news.sohu.com/20161024/n471131905.shtml");                execute.setEnabled(false);                cancel.setEnabled(true);            }        });        cancel = (Button) findViewById(R.id.cancel);        cancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //取消一个正在执行的任务,onCancelled方法将会被调用                mTask.cancel(true);            }        });        progressBar = (ProgressBar) findViewById(R.id.progress_bar);        textView = (TextView) findViewById(R.id.text_view);    }    private class MyTask extends AsyncTask<String, Integer, String> {        //onPreExecute方法用于在执行后台任务前做一些UI操作        @Override        protected void onPreExecute() {            Log.i(TAG, "onPreExecute() called");            textView.setText("loading...");        }        //doInBackground方法内部执行后台任务,不可在此方法内修改UI        @Override        protected String doInBackground(String... params) {            Log.i(TAG, "doInBackground(Params... params) called");            try {                URL url = new URL(params[0]);                HttpURLConnection connection = (HttpURLConnection) url.openConnection();                connection.setRequestMethod("GET");                connection.setDoInput(true);                connection.setRequestProperty("contentType", "GBK");                connection.setRequestProperty("Accept-Encoding", "identity");                connection.setConnectTimeout(8000);                connection.setReadTimeout(8000);               // connection.getContentLengthLong();                Log.i(TAG, "1"+connection.getResponseCode());                if (connection.getResponseCode() == 200) {                    // 获取响应的输入流对象                    InputStream inputStream = connection.getInputStream();                    // 创建字节输出流对象                    ByteArrayOutputStream message = new ByteArrayOutputStream();                    // 定义读取的长度                    int len = -1;                    int count=0;                    // 定义缓冲区                    byte buffer[] = new byte[1024];                    long total = 102400;                    total = connection.getContentLength();                    Log.e(TAG, "total = "+total);                    // 按照缓冲区的大小,循环读取                    while ((len = inputStream.read(buffer)) != -1) {                        // 根据读取的长度写入到os对象中                        message.write(buffer, 0, len);                        count += len;                        //调用publishProgress公布进度,最后onProgressUpdate方法将被执行                        publishProgress((int) ((count / (float) total) * 100));                        //为了演示进度,休眠500毫秒                        Thread.sleep(500);                    }                    return new String(message.toByteArray(), "utf-8");                }            } catch (Exception e) {                Log.e(TAG, e.getMessage());            }            return null;        }        //onProgressUpdate方法用于更新进度信息        @Override        protected void onProgressUpdate(Integer... progresses) {            Log.i(TAG, "onProgressUpdate(Progress... progresses) called");            progressBar.setProgress(progresses[0]);            textView.setText("loading..." + progresses[0] + "%");        }        //onPostExecute方法用于在执行完后台任务后更新UI,显示结果        @Override        protected void onPostExecute(String result) {            Log.i(TAG, "onPostExecute(Result result) called");            textView.setText(result);            Log.i(TAG,result);            execute.setEnabled(true);            cancel.setEnabled(false);        }        //onCancelled方法用于在取消执行中的任务时更改UI        @Override        protected void onCancelled() {            Log.i(TAG, "onCancelled() called");            textView.setText("cancelled");            progressBar.setProgress(0);            execute.setEnabled(true);            cancel.setEnabled(false);        }    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <Button        android:id="@+id/execute"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="execute"/>    <Button        android:id="@+id/cancel"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:enabled="false"        android:text="cancel"/>    <ProgressBar        android:id="@+id/progress_bar"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:progress="0"        android:max="100"        style="?android:attr/progressBarStyleHorizontal"/>    <ScrollView        android:layout_width="fill_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/text_view"            android:layout_width="fill_parent"            android:layout_height="wrap_content"/>    </ScrollView></LinearLayout>


 

 

 

0 0