Android多线程编程
2015-12-26 21:29
405 查看
(来自《第一行代码》)整理总结
JAVA中的多线程
1、 继承Thread
2、实现Runnable
3、匿名类的方式(最常用)
一、使用Handler(处理者)在子线程中更新UI:
机制:
1、Message是线程之间传递的消息,可以使用what字段,还可以使用arg1和arg2字段来携带一些整形数据,使用obj字段携带一个Object对象。
2、Handler主要用于发送和处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到Handler的handleMessage()。
3、MessageQueue是消息队列的消息,主要用于存放所有通过Handler发送的消息,这些消息一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。
4、Looper是每个线程中的MessageQueue的管家。每个线程中也只会有一个Looper对象。负责将消息队列中的消息传递到Handler的handleMessage()的方法中。
过程:1、主线程创建Handler对象,重写handleMessage()方法;
2、在子线程中创建Message对象,然后发送;
3、消息被添加到消息队列中,Looper取出消息,分发到handleMessage()方法中安心地进行UI操作。
二、使用AsyncTask
两者比较:
AsyncTask在代码上比Handler要轻量级,而实际上要比Handler更耗资源,因为AsyncTask底层是一个线程池,而Handler仅仅是发送了一个消息队列。
但是,如果异步任务的数据特别庞大,AsyncTask线程池的结构优势就体现出来。
JAVA中的多线程
1、 继承Thread
class MyThread extends Thread { @override public void run() { // 具体的处理逻辑 } }
new MyThread().start();
2、实现Runnable
class MyThread implements Runnable { @override public void run() { // 具体的处理逻辑 } }
MyThread myThread = new MyThread(); new Thread(myThread).start();
3、匿名类的方式(最常用)
new Thread(new Runnable() { @Override public void run() { // 处理具体的逻辑 } }).start();
一、使用Handler(处理者)在子线程中更新UI:
<RelativeLayout 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" > <Button android:id="@+id/change_text" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Change Text" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Hello world" android:textSize="20sp" /> </RelativeLayout>
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { public static final int UPDATE_TEXT = 1;// 表示更新TextView这个动作 private TextView text; private Button changeText; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: text.setText("Nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.text); changeText = (Button) findViewById(R.id.change_text); changeText.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.change_text: new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); } }).start(); break; default: break; } } }
机制:
1、Message是线程之间传递的消息,可以使用what字段,还可以使用arg1和arg2字段来携带一些整形数据,使用obj字段携带一个Object对象。
2、Handler主要用于发送和处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到Handler的handleMessage()。
3、MessageQueue是消息队列的消息,主要用于存放所有通过Handler发送的消息,这些消息一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。
4、Looper是每个线程中的MessageQueue的管家。每个线程中也只会有一个Looper对象。负责将消息队列中的消息传递到Handler的handleMessage()的方法中。
过程:1、主线程创建Handler对象,重写handleMessage()方法;
2、在子线程中创建Message对象,然后发送;
3、消息被添加到消息队列中,Looper取出消息,分发到handleMessage()方法中安心地进行UI操作。
二、使用AsyncTask
/** * AsyncTask基本用法 * * @author Administrator * */ class DownloadTask extends AsyncTask<Void, Integer, Boolean> { // 三个参数分别表示(Params)在执行AsyncTask时需要传入的参数; // (Progress)当前的进度; // (Result)任务处理执行完毕后返回的结果 private ProgressDialog progressDialog; private String[] valus; private Context context; private int doDownload() { // TODO Auto-generated method stub return 0; } // 界面上的初始化操作,比如显示一个进度条对话框 @Override protected void onPreExecute() { // 显示进度对话框 progressDialog.show(); } // 在子线程中运行,处理耗时的任务 @Override protected Boolean doInBackground(Void... params) { try { while (true) { // 这是一个虚构的方法 int downloadPercent = doDownload(); // 调用publishProgress(Progress...)反馈当前任务的执行进度 publishProgress(downloadPercent); if (downloadPercent >= 100) { break; } } } catch (Exception e) { return false; } return true; } // 在任务中调用publishProgress(Progress...)后,这个方法很快被调用,在这里可进行UI操作 @Override protected void onProgressUpdate(Integer... values) { // 在这里更新下载进度 progressDialog.setMessage("Downloaded " + valus[0] + "%"); } // 后台任务执行完毕并通过return语句进行返回,这个方法被调用,可利用返回的数据进行UI操作(收尾工作) @Override protected void onPostExecute(Boolean result) { // 关闭进度对话框 progressDialog.dismiss(); // 提醒任务执行的结果 if (result) { Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "Download failed", Toast.LENGTH_SHORT).show(); } }
两者比较:
AsyncTask在代码上比Handler要轻量级,而实际上要比Handler更耗资源,因为AsyncTask底层是一个线程池,而Handler仅仅是发送了一个消息队列。
但是,如果异步任务的数据特别庞大,AsyncTask线程池的结构优势就体现出来。
相关文章推荐
- android设置默认输入法
- Android 新support库大集结
- Android自己定义组件系列【9】——Canvas绘制折线图
- Android_照相机Camera_使用intent调用系统照相机在onActivityResult返回data为空
- Andriod获取系统自带铃声
- Android 自己写一个打开图片的Activity
- 浅析ListView用法
- 【转】 Android学习笔记(21…
- [转]android声音调整源代码分析
- 【转】Android R.java文件丢…
- 【转】android 自定义progres…
- 【转】android利用VideoView实现视…
- 【转】android Videoview&nbs…
- 【转】Android三种播放视频的方式
- android 获取Bitmap 的两种方法
- android导入第三方jar包报错 …
- Android 禁止系统休眠,使屏…
- Android点击事件实例之通过…
- Android开发 旋转屏幕导致Act…
- Android反编译