同步任务:
在执行程序时,没有收到 执行结果,就等,不继续往下执行,
直到收到执行结果,才接着往下执行
异步任务:
在执行程序时,如果遇到需要等待的任务,就开辟一个子线程去执行它,
自己继续往下执行其他程序。子线程有结果时,会将结果发送给主线程。
举例子:
小新在家请客,客人源源不断的来,这时候小新需要执行的任务:
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;
}