android的异步任务与handler分析与初步实战

同步任务:
在执行程序时,没有收到 执行结果,就等,不继续往下执行,
直到收到执行结果,才接着往下执行

异步任务:
在执行程序时,如果遇到需要等待的任务,就开辟一个子线程去执行它,
自己继续往下执行其他程序。子线程有结果时,会将结果发送给主线程

举例子:
小新在家请客,客人源源不断的来,这时候小新需要执行的任务:
1.接待客人(打招呼聊天)
2.准备晚饭
同步的执行任务:小新去准备晚饭,这个过程可能要2小时,小新就一直在厨房忙活
直到做好饭,才出来跟客人聊天

异步的执行任务:小新一看晚饭需要一段时间,自己做就没法接待客人了,
就临时找了一个厨师回来做饭了,自己不用等饭做好,就可以去陪客人聊天了。
等厨师把饭做好。小新就可以愉快的和客人共进晚餐了。

Android中的多线程
线程:通俗讲就是一个执行过程.多线程,就是多个执行过程。

为什么要有多线程?
程序中多个任务,如果只有一个线程,那莫就只能一个接一个的执行了,
类似 同步执行任务,很明显的慢,因为只有上一个任务执行完,才能进行下一个。
因此,我们需要 多线程来分别执行 这些任务。也就是异步执行任务

类比到我们Android的app程序。App一启动,就是一个线程,这个线程被称为主线程mainThread,
负责显示界面,和用户交互。
另外,界面通常被称为ui,因此主线程也被称为ui线程

两个原则:
主线程不能执行网络请求/文件读写等耗时操作
子线程不能执行UI刷新

handler机制
android中界面无响应会报ANR,主线程阻塞报ANR,通过handle等子线程进行解决
handler通过SendMessage发送消息,消息存放在管道消息队列MessageQueue中,
MessageQueue队列里有一个取消息的工具叫Looper,有消息就往外面拿,会轮询的查
再返回给Handler,兜了一圈回来了。。。handler接收到looper取到消息,
就可以通过HandleMessage方法处理拿到的消息了
图示画面感:
在这里插入图片描述

实战举例子:
代码展示xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".handler.HandlerActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="结果"
        />
    <Button
        android:id="@+id/btn_success"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:onClick="start"
        android:text="开始"
         />


</LinearLayout>

代码展示:java代码:

package com.studay.base.study.handler;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.studay.base.study.R;

public class HandlerActivity extends AppCompatActivity {


    private TextView tvContext;
    String stringFromNet;
    //Looper来遍历消息取对象
    Handler mHandler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 6) {
                String obj = (String) msg.obj;
                tvContext.setText(obj);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
          tvContext=findViewById(R.id.tv_tv);
    }

    //在xml里点击事件绑定这个方法的话,必须加上View参数
    public void start(View view) {

        //做一个耗时任务
        new Thread(new Runnable() {
            @Override
            public void run() {
                String str = getStringFromNet();
                Message message = new Message();
                message.what = 6;
                message.obj = str;
                //主线程的handler给主线程发消息
                mHandler.sendMessage(message);
            }
        }).start();
        Toast.makeText(this, "任务完成啦", Toast.LENGTH_LONG).show();
    }

    public String getStringFromNet() {
        //假装从网络获取了一个字符串
        String result = "";
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < 30; i++) {
            stringBuilder.append("字符串" + i);
        }

        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        result=stringBuilder.toString();
        return result;
    }

猜你喜欢

转载自blog.csdn.net/ShiXinXin_Harbour/article/details/127399518