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中实现异步任务机制的方式有两种方式:Handler和AsyncTask
一、异步消息处理机制
Android 异步消息处理主要由四个部分组成:Message、MessageQueue、Handler、Looper
(1)Message
线程之间传递的消息,它在内部携带信息,用于不同线程之间交换数据。
(2)MessageQueue
消息队列,主要是用于存放Handler发送的消息,这些消息会一直存在于消息队列中等待处理。每个线程只有一个MessageQueue
(3)Handler
主要用于消息的发送和消息的处理。发送的消息一般是使用Handler的sendMessage()方法,处理消息是使用Handler的方法handlerMessage()方法。
(4)Looper
是每个线程中MessageQueue的管家,调用Looper中的loop()方法之后,就会进入一个无线循环中,一发现MessageQueue中的消息,就会将其取出并将其传递到Handler中的handlerMessage方法中进行处理。
异步消息的整个处理流程:
当我们需要进行UI操作,我们将一个消息通过Handler的方法sendMessage将消息发送到MessageQueue中等待被处理,Looper将Message从MessageQueue中取出并将其发送到Handler的handlerMessage方法中,由于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)doInBackground(Params.....),在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>
- Handler机制和AsyncTask机制的使用
- Handler机制和AsyncTask
- Android开发之Handler机制及AsyncTask的使用
- Handler机制、AsyncTask
- android handler机制和Timer的使用
- Handler机制,AsyncTask与aidl
- android os;异步消息处理机制:AsyncTask和Handler
- 线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- Android中AsyncTask(异步任务)和Handler(线程消息机制)的详解
- Android中实现异步任务机制的方式:Handler、AsyncTask
- 异步消息处理机制-Handler、AsyncTask
- 多线程异步机制Handler以及AsyncTask
- handler机制和两种使用
- AsyncTask的实现机制
- 【Android开发】线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- 【Android开发】线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- 浅谈handler使用机制
- Handler机制使用法则
- 微信热升级tinker集成项目
- Linux下的 Linux 终端仿真器Terminator
- Spring框架学习
- handsontable选中列,按键盘delete键,整列数据清除,如何禁止
- opencv2.4.10 安装与vs2013配置
- Handler机制和AsyncTask机制的使用
- 初识react
- 13、Spring MVC 之 Using themes
- 十月第四周周报
- SpringMVC入门笔记(一)
- 2016.10.24
- 常用正则表达式总结
- 分布式拒绝服务攻击(DDOS)攻击原理
- Oracle_12505错误解决方法