关于Android多线程编译

关于Android多线程编译Android 多线程编译的问题一直都是 HR 青睐的面试题 因为多线程编译在 Android 开发过程中占有一定的地位 如果我们把一个耗时操作放在主线程中 就会导致主线程被阻塞 影响软件的正常使用 所以我们一般会把一个耗时任务放在一个子线程中 那如果是多个耗时任务呢 所以就有了多线程编译 Android 中是怎么创建一个线程的呢 办法有三个 1 新建一个类继承自 Thread 然后重写父类的 run 方法 然

Android多线程编译的问题一直都是HR青睐的面试题,因为多线程编译在Android开发过程中占有一定的地位。如果我们把一个耗时操作放在主线程中,就会导致主线程被阻塞,影响软件的正常使用。所以我们一般会把一个耗时任务放在一个子线程中,那如果是多个耗时任务呢?所以就有了多线程编译。

Android中是怎么创建一个线程的呢?办法有三个:

1.新建一个类继承自Thread,然后重写父类的run()方法,然后把耗时逻辑编写在里面,如:

class MyThread extends Thread{ @Override public void run() { super.run(); //处理逻辑写这里 } }

然后我们通过new一个MyThread的实例,调用start()方法: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();

       通过上面的学习你已经对线程的创建和使用有了一定的了解,那么你是否知道在Android中,UI的更新是不能在子线程中进行的。Android的UI线程是不安全的,我们要更新应用程序的UI元素,必须在主线程中进行,否侧就会出现异常。那么我们怎么样才能在子线程中进行UI操作呢?

关于Android多线程编译

此图是百度找的,如若有侵权请联系版主删除图片

1.Message

2.Handler

3.MessageQueue

        MessageQueue主要是用于存放所有通过Handler发送的消息,它相当于一个消息队列。要记住的是每个线程只会有一个MessageQueue对象。

4.Looper

        现在我们应该对这四个部分有了初步的了解了,现在我们来捋捋Android异步消息处理机制的整个流程。首先要在主线程当中创建一个Handler对象,并重写handlerMessage()方法。然后当子线程中有需要进行UI操作时,就要创建一个Message对象,并通过Handler对象的sendMessage()方法把这条消息发送出去。之后这调消息会存储在MessageQueue的队列中等待被处理,而Looper此时会一直尝试从MessageQueue中取出待处理的消息,最后分发回Handler的handlerMessage()方法中。但是由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,这样就能达到了我们想要的效果,这就是异步消息处理的核心思想。弄懂了原理后我们在代码上实现一下看看效果是不是如我们所想,上个最简单的例子,我们做一个能通过点击按钮然后改变文本控件显示的内容的功能来试试。上代码图:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{ final static int CHANGE_TEXT = 1;//先定义一个整型变量来表示更新TextView这个动作 private Button bt_change; private TextView tv_texr; Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case CHANGE_TEXT: tv_texr.setText("我变了");//接收到消息后改变textview里面的文本 } } };//创建Handler对象在主线程 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_change = (Button) findViewById(R.id.bt_change); tv_texr = (TextView)findViewById(R.id.tv_text); bt_change.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.bt_change: new Thread(new Runnable() { @Override public void run() { Message message = new Message();//实例化一个Message对象 message.what = CHANGE_TEXT;//通过what字段存储消息 handler.sendMessage(message);//使用handler对象的sendMessage方法把这条消息发送到handlerMessage方法中 } }).start();//通过创建一个匿名类的方式去创建一个子线程 break; } } }

        上面代码的基本思路是:先定义一个整型变量CHANGE_TEXT,用于表示更新TextView的文本内容这个动作。然后实例化一个Handler对象,并重写handlerMessage()方法,对发送的Message的what字段进行处理,如果等于CHANGE_TEXT,就将TextView显示的文本内容进行相应的变化。那我们的Message是从哪来的呢?这里我实现了点击监听事件的接口,当我们点击bt_change这个按钮时,我们就以匿名类的方式创建一个子线程,并在子线程中实例化一个Message对象。之后我们把Message对象的what字段的值指向了CHANGE_TEXT,然后调用Handler的sendMessage()方法把这个消息发送出去。这样就完美的解决了在子线程中更新UI界面的功能了。

        当然大家如果有兴趣的话,其实Android还提供了另外一个可以处理异步消息的工具——AsyncTask,你们可以去了解了解一下这个工具。它不需要你去深入了解异步消息处理机制,也可以在子线程切换到主线程。但是它其实实现的原理都一样,只是Android帮我们做好了封装,我们可以直接使用它而不需要懂其中的运行原理,我在这里就不详细介绍了。

转载的小伙伴请表明原创出处:原创链接

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211612.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午10:01
下一篇 2026年3月18日 下午10:02


相关推荐

  • select2 使用教程(简)「建议收藏」

    select2 使用教程(简)「建议收藏」用了这么久的Select2插件,也该写篇文章总结总结。当初感觉Select2不是特别好用,但又找不到比它更好的下拉框插件。在我的印象里Select2有2个版本,最新版本有一些新的特性,并且更新了一下方法参数,比最初版本要好看一些,本文针对新版本。官网:http://select2.github.io/演示:请选择由于博客系统的原因,所以只能演示简单

    2022年6月25日
    33
  • Workbench中直接调用ICEM CFD进行网格划分「建议收藏」

    Workbench中直接调用ICEM CFD进行网格划分「建议收藏」Workbench中直接调用ICEMCFD进行网格划分自从ANSYS12.0之后,ICEMCFD就从Workbench中被分离出去,作为一个独立的程序使用了。取而代之的是Meshing模块。在Meshing的属性节点菜单中右键点击Mesh,选择Insert>Method,插入方法。选择需要划分网格的几何体,点击apply。此时Geometry显示为1Body。设置Method为MultiZone,如果不设置成这个的话,找不到进入ICEMCFD的入口。如果要划分四面体,

    2022年5月9日
    161
  • idea激活 jetbrains-agent(jetbrains激活码)

    一、下载jar包JetbrainsCrack-2.7-release-str.jar百度这个jar包名字很多资源最好是找最新的二、找到软件的安装路径下的bin目录;将下载的jar包放到bin目录下,并将datagrip64.exe.vmoptions、datagrip.exe.vmoptions两个文件末尾添加一行代码-javaagent:C:\JetBrains\DataGri…

    2022年4月14日
    2.1K
  • js生成的随机数的方法

    js生成的随机数的方法js 生成随数

    2026年3月17日
    1
  • leetcode-149. 直线上最多的点数(map+判重)[通俗易懂]

    leetcode-149. 直线上最多的点数(map+判重)[通俗易懂]给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。示例 1:输入: [[1,1],[2,2],[3,3]]输出: 3解释:^|| o| o| o +————->0 1 2 3 4示例 2:输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]输出: 4解释:^|| o| o o| o| o o+—–

    2022年8月11日
    5
  • url加时间戳避免再次请求当前路径出现的缓存问题[通俗易懂]

    url加时间戳避免再次请求当前路径出现的缓存问题[通俗易懂]1.先解释一下,为什么要加时间戳: URL后面添加随机数通常用于防止客户端(浏览器)缓存页面。浏览器缓存是基于url进行缓存的,如果页面允许缓存,则在一定时间内(缓存时效时间前)再次访问相同的URL,浏览器就不会再次发送请求到服务器端,而是直接从缓存中获取指定资源。2.加时间戳的方法:[javascript] viewplain copy

    2022年5月1日
    224

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号