线程的基本用法:

android多线程编程其实并不比java多线程特殊,基本都是使用相同的语法,比如说,定义一个线程只需要新建一个类继承自Thread,然后重写父类的run()方法,并在里面编写耗时的逻辑即可,

public classMyThread extends Thread {

@Overridepublic voidrun() {//处理具体的逻辑

super.run();

}

}

如何启动这个线程,其实也很简单,只需要new出MyThread的实例,然后调用它的start()方法,这样run()方法中的代码就会在子线程当中运行了。

new MyThread().start();

使用继承的方式耦合性有点高,更多的时候我们都会选择使用Runnable接口的方式定义一个线程

public classMyThread implements Runnable{

@Overridepublic voidrun() {//处理具体的逻辑

}

}

如果使用了这种写法,启动线程的方法也需要进行相应的改变,

MyThread mythread=new MyThread();

new Thread(mythread).start();

当然如果不想专门再定义一个类去实现runnable接口,也可以使用匿名累的方式,如下所示:

Thread thread= new Thread(newRunnable() {

@Overridepublic voidrun() {//具体处理逻辑

}

}).start();

再子线程中更新UI

和许多其他GUI库一样,安卓的UI也是线程不安全的,也就是说,如果想要更新应用程序里的UI元素,则必须在主线程中进行,否则就会出现异常。

下面我们来看一个例子:

android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/change_text"android:text="send request"/>

android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/text1"android:text="hello world"android:textSize="20sp"

/>

public classMainActivity extends Activity implements View.OnClickListener {privateTextView textView;privateButton changeText;

@Overrideprotected voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

textView=(TextView)findViewById(R.id.text1);

changeText=(Button)findViewById(R.id.change_text);

changeText.setOnClickListener(this);

}

@Overridepublic voidonClick(View v) {switch(v.getId()){caseR.id.change_text:new Thread(newRunnable() {

@Overridepublic voidrun() {

textView.setText("Nice to neet you");

}

}).start();break;default:break;

}

}

运行的时候会出现如下图所示的情况:

由此正式了安卓确实是不允许自线程中运行UI操作,但是有时候我们必须在子线程里面去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件,

安卓提供了一套异步消息处理机制完美的解决了在子线程中运行UI操作。

首先我们先来看一下这个解决的代码

public classMainActivity extends Activity implements View.OnClickListener {privateTextView textView;privateButton changeText;public static final int UPDATE_TEXT=1;private Handler handler=newHandler() {

@Overridepublic voidclose() {

}

@Overridepublic voidflush() {

}

@Overridepublic voidpublish(LogRecord record) {

}public voidhandleMessage(Message msg){switch(msg.what){caseUPDATE_TEXT:

textView.setText("Nice to meet you");break;default:break;

}

}

};

@Overrideprotected voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

textView=(TextView)findViewById(R.id.text1);

changeText=(Button)findViewById(R.id.change_text);

changeText.setOnClickListener(this);

}

@Overridepublic voidonClick(View v) {switch(v.getId()){caseR.id.change_text:new Thread(newRunnable() {

@Overridepublic voidrun() {

Message message=newMessage();

message.what=UPDATE_TEXT;

handler.sendMessage(message);

}

}).start();break;default:break;

}

}

我们来解析异步消息处理机制:

安卓中的异步消息处理主要由四部分组成,Message,Handler,MessageQueue和Looper。

1 Message

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

2 Handler

Handler故名思义也就是处理者的意思,它主要是用于发送和处理消息的,发送消息一般是使用Handler的sendmessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到Handler地handleMessage()方法中,

3MessageQueue

MessageQueue 是消息队列的意思,它主要用于存放所有通过Handler发送的消息,这部分消息会一直存在于消息队列中,等待被处理,每个线程中只会有一个MessageQueue对象。

4 Looper

Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入到一个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handleMessage()方法中,每个线程中也只会只有一个Looper对象。

首先需要在主线成中创建一个Handler对象,并重写handleMessage()方法,然后子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去,之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后奋发回Handler的handleMessage()方法中,由于Handle是在主线程中创建的,所以此时handleMessage()方法中的代码也会在主线成中运行,于是我们在这里就可以安心的运行UI操作,整个异步消息处理的核心思想就是这样。

为了更加方便我们在自线程中对UI进行操作,android还提供了另外的一些好用的工具,AsyncTask就是其中之一,借助AsyncTask,即使你对异步消息处理机制完全不了解,也可以十分简单的从子线程切换的主线程,AsyncTask背后的实现原理也是基于异步消息处理机制的。

由于AsyncTask是一个抽象类,所以如果我们想要使用它,就必须创建一个子类去继承它,在继承AsyncTask类指定三个范性参数,这三个参数的用途如下:

1 params

在执行AsyncTask时需要传入参数,用于在后台任务中使用。

2progress

后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的范性作为进度单位。

3 result

当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回类型。

我们还需要自定义一些方法才能完成对任务的定制。

1 onPreExecute()

这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框

2 doInBackground(Params...)

这个方法中所有代码都会在自线程中运行,我们应该在这里去处理所有的耗时任务,任务一旦完成就可以通过return语句来将任务的执行结果返回,如果AsyncTask的读三个泛型参数指定的是void,就可以不返回任务执行结果,注意,在这个方法中是不可以进行ui操作的,如果要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。

3 onProgressUpdate(Progress...)

当在后台任务中调用了publishprogress(progress...)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务传递过来的,在这个方法中可以对UI进行操作。利用参数中的数值就可以对界面元素进行相应的更新。

4 onPostExecute(Result)

当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用,返回的数据会作为位参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果以及关闭掉进度条对话框。

如果要启动的话只需要调用其execute()方法。

android--多线程,android多线程相关推荐

  1. Android中的多线程(字节跳动)

    文章目录 Handler机制(Android中的消息队列机制) Handler机制为Android系统解决了以下两个问题 Handler常用方法 Handler的使用 补充知识点 Handler原理 ...

  2. android设计一个多线程和画图的程序小球,Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能实例...

    本文实例讲述了Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能的方法.分享给大家供大家参考,具体如下: 1.布局界面 xmlns:tools="http://sc ...

  3. (Android小应用)在Android中实现多线程断点下载(连载二)

    前面已经讲了通过多线程下载网络文件的一部分核心代码,下面继续做我们的项目 当然如果我们做小一点的Android项目的时候可以先做界面,然后根据需要来扩展所需要的功能,当然有的时候我们宁愿先实现业务,业 ...

  4. Android开发之多线程编程Thread和Runnable使用

    Android开发之多线程编程Thread和Runnable使用 Android可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:前者只要继承了Thread类同时覆写了 ...

  5. Android中的多线程编程与异步处理

    Android中的多线程编程与异步处理 引言 在移动应用开发中,用户体验是至关重要的.一个流畅.高效的应用能够吸引用户并提升用户满意度.然而,移动应用面临着处理复杂业务逻辑.响应用户输入.处理网络请求 ...

  6. android 多文件多线程断点续传下载

    今天跟大家一起分享下android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...

  7. Android进阶:多线程断点续传下载

    今天跟大家一起分享下android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的. 什么是多线程下载? 多线程下载其实就是迅雷, ...

  8. Android基础篇-多线程下载(一)

    效果图 下载文件: 讲解: 多线程下载多个文件: 下载首先就必须明白http协议,不会的读者:请点击这里 首先我们知道关于操作网络我们是不能直接在UI(主)线程中直接操作的,所以这里我们就得开启线程 ...

  9. android 之使用多线程中的AsyncTask实现下载网络图片资源

    前台显示: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:androi ...

  10. android之android.intent.category.DEFAULT的用途和使用

    1.要弄清楚这个问题,首先需要弄明白什么是implicit(隐藏) intent什么是explicit(明确) intent. Explicit Intent明确的指定了要启动的Acitivity , ...

最新文章

  1. 30 万奖金悬赏 | CSDN 软件开发精英赛即日启动!
  2. 八成Java开发者解答不了的问题
  3. 机房六大安防系统常见故障原因及处理方法
  4. C#获取txt记事本内容,防止乱码情况
  5. MySQL_数据库表记录的操作
  6. Mac上配置Privoxy
  7. 1D和2D条码生成、检测、识别控件Barcode Xpress
  8. 关于COM类工厂80070005和8000401a错误分析及解决办法
  9. NandFlah 相关知识详解
  10. elementUI中upload上传组件点击上传按钮,选择文件框弹出前进行提示点击确定则继续弹框选择文件上传
  11. 计算机无法删除tf卡的内容,内存卡的文件删不掉怎么办?
  12. golang中的错误fatal error: concurrent map writes
  13. 2017年终总结——恍恍惚惚又一年
  14. CSDN 社区年终总结|回顾 2021
  15. qq空间进入游戏显示服务器拒绝,显示ptlogin2.qq.com,QQ空间打不开的快速解决办法...
  16. 中国传感器制造行业发展态势与应用前景预测报告2022-2028年
  17. 商汤的AI伴游小精灵
  18. switch vba_VBA switch
  19. 某大厂来的水货CTO,写出了新手都不会犯的低级 Bug,被骗300W!就里就不点名了!...
  20. 单片机基础入门:什么是上电复位,复位电路怎么设计

热门文章

  1. kailinux mysql提权_linux下mysql提权
  2. python 寻找数组的中心索引_Leetcode724查找数组Python的中心索引,LeetCode724,寻找,python...
  3. 实战:隐藏SpringBoot中的私密数据!
  4. 阿里巴巴为什么禁止使用Apache Beanutils进行属性复制?
  5. 程序员专属精品简历合集—面试必备
  6. Asp.Net使用Yahoo.Yui.Compressor.dll压缩Js|Css
  7. Cookie的设置获取和删除
  8. Windows MinGW配置C、C++编译环境
  9. CV2 puttext不能显示中文问题
  10. C#利用反射将Datatable转化为指定实体类ListT