Android Studio App开发中异步任务AsynTask与异步服务IntentService的讲解与实战(实现四大名著的加载进度条 附源码)

简介: Android Studio App开发中异步任务AsynTask与异步服务IntentService的讲解与实战(实现四大名著的加载进度条 附源码)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~

一、异步任务AsyncTask

Thread+Handler方式虽然能够实现线程间通信,但是代码编写非常麻烦,并且难以维护,为了解决这个问题,Android提供了AsyncTask这个轻量级的异步任务工具,其内部已经封装好了Thread+Handler的通信机制。它是一个模板类,从他派生而来的任务类需要指定模板的参数类型

1:params 创建任务时的输入参数

2:Progress 执行任务时的处理进度

3:Result 完成任务时的结果参数

开发者自定义的任务类需要实现以下方法

1:onPreExecute 准备执行任务时触发

2:doInBackground 在后台执行的业务处理

3:onProgressUpdate  通常在处理过程中刷新进度条

4:onPostExecute  任务执行完毕时触发 显示处理结果

5:onCancelled 任务取消的回调操作

下面举个例子,电子书来自网络,要等它加载完毕后用户才能浏览电子书内容,于是编写电子书的异步加载任务,在界面上动态显示当前的加载进度,全部完成后再提示用户已经加载完毕。

代码如下

Java类

package com.example.chapter11;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter11.task.BookLoadTask;
import com.example.chapter11.task.BookLoadTask.OnProgressListener;
@SuppressLint(value={"SetTextI18n","DefaultLocale"})
public class AsyncTaskActivity extends AppCompatActivity implements OnProgressListener {
    private TextView tv_async;
    private ProgressBar pb_async; // 声明一个进度条对象
    private ProgressDialog dialog; // 声明一个进度对话框对象
    public int mShowStyle; // 显示风格
    public int BAR_HORIZONTAL = 1; // 水平条
    public int DIALOG_CIRCLE = 2; // 圆圈对话框
    public int DIALOG_HORIZONTAL = 3; // 水平对话框
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
        tv_async = findViewById(R.id.tv_async);
        // 从布局文件中获取名叫pb_async的进度条
        pb_async = findViewById(R.id.pb_async);
        initBookSpinner(); // 初始化书籍选择下拉框
    }
    // 初始化书籍选择下拉框
    private void initBookSpinner() {
        ArrayAdapter<String> styleAdapter = new ArrayAdapter<String>(this,
                R.layout.item_select, bookArray);
        Spinner sp_style = findViewById(R.id.sp_style);
        sp_style.setPrompt("请选择要加载的小说");
        sp_style.setAdapter(styleAdapter);
        sp_style.setOnItemSelectedListener(new StyleSelectedListener());
        sp_style.setSelection(0);
    }
    private String[] bookArray = {"三国演义", "西游记", "红楼梦"};
    private int[] styleArray = {BAR_HORIZONTAL, DIALOG_CIRCLE, DIALOG_HORIZONTAL};
    class StyleSelectedListener implements OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            startTask(styleArray[arg2], bookArray[arg2]); // 启动书籍加载线程
        }
        public void onNothingSelected(AdapterView<?> arg0) {}
    }
    // 启动书籍加载线程
    private void startTask(int style, String book) {
        mShowStyle = style;
        BookLoadTask task = new BookLoadTask(book); // 创建一个书籍加载线程
        task.setOnProgressListener(this); // 设置书籍加载监听器
        task.execute(book); // 把书籍加载线程加入到处理列表
    }
    // 关闭对话框
    private void closeDialog() {
        if (dialog != null && dialog.isShowing()) { // 对话框仍在显示
            dialog.dismiss(); // 关闭对话框
        }
    }
    // 在线程处理结束时触发
    public void onFinish(String book) {
        String desc = String.format("您要阅读的《%s》已经加载完毕", book);
        tv_async.setText(desc);
        closeDialog(); // 关闭对话框
    }
    // 在线程处理取消时触发
    public void onCancel(String result) {}
    // 在线程处理过程中更新进度时触发
    public void onUpdate(String book, int progress) {
        String desc = String.format("%s当前加载进度为%d%%", book, progress);
        tv_async.setText(desc); // 设置加载进度的文本内容
        if (mShowStyle == BAR_HORIZONTAL) { // 水平条
            pb_async.setProgress(progress); // 设置水平进度条的当前进度
        } else if (mShowStyle == DIALOG_HORIZONTAL) { // 水平对话框
            dialog.setProgress(progress); // 设置水平进度对话框的当前进度
        }
    }
    // 在线程处理开始时触发
    public void onBegin(String book) {
        tv_async.setText(book + "开始加载");
        if (dialog == null || !dialog.isShowing()) {  // 进度框未弹出
            if (mShowStyle == DIALOG_CIRCLE) { // 圆圈对话框
                // 弹出带有提示文字的圆圈进度对话框
                dialog = ProgressDialog.show(this, "稍等", book + "页面加载中……");
            } else if (mShowStyle == DIALOG_HORIZONTAL) { // 水平对话框
                dialog = new ProgressDialog(this); // 创建一个进度对话框
                dialog.setTitle("稍等"); // 设置进度对话框的标题文本
                dialog.setMessage(book + "页面加载中……"); // 设置进度对话框的内容文本
                dialog.setIcon(R.drawable.ic_search); // 设置进度对话框的图标
                dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 设置进度样式
                dialog.show(); // 显示进度对话框
            }
        }
    }
}

任务类

package com.example.chapter11.task;
import android.os.AsyncTask;
// 模拟异步处理的线程
public class BookLoadTask extends AsyncTask<String, Integer, String> {
    private String mBook; // 书籍名称
    public BookLoadTask(String title) {
        super();
        mBook = title;
    }
    // 线程正在后台处理
    protected String doInBackground(String... params) {
        int ratio = 0; // 下载比例
        for (; ratio <= 100; ratio += 5) {
            try {
                Thread.sleep(200); // 睡眠200毫秒模拟网络文件下载耗时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            publishProgress(ratio); // 通报处理进展。调用该方法会触发onProgressUpdate方法
        }
        return params[0]; // 返回参数是书籍的名称
    }
    // 准备启动线程
    protected void onPreExecute() {
        mListener.onBegin(mBook); // 触发监听器的开始事件
    }
    // 线程在通报处理进展
    protected void onProgressUpdate(Integer... values) {
        mListener.onUpdate(mBook, values[0]); // 触发监听器的进度更新事件
    }
    // 线程已经完成处理
    protected void onPostExecute(String result) {
        mListener.onFinish(result); // 触发监听器的结束事件
    }
    // 线程已经取消
    protected void onCancelled(String result) {
        mListener.onCancel(result); // 触发监听器的取消事件
    }
    private OnProgressListener mListener; // 声明一个进度更新的监听器对象
    // 设置进度更新的监听器
    public void setOnProgressListener(OnProgressListener listener) {
        mListener = listener;
    }
    // 定义一个进度更新的监听器接口
    public interface OnProgressListener {
        void onBegin(String book); // 在线程处理开始时触发
        void onUpdate(String book, int progress); // 在线程处理过程中更新进度时触发
        void onFinish(String book); // 在线程处理结束时触发
        void onCancel(String book); // 在线程处理取消时触发
    }
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp" >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >
        <TextView
            android:id="@+id/tv_style"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:gravity="center"
            android:text="请选择要加载的小说 "
            android:textColor="@color/black"
            android:textSize="17sp" />
        <Spinner
            android:id="@+id/sp_style"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_toRightOf="@+id/tv_style"
            android:gravity="left|center"
            android:spinnerMode="dialog" />
    </RelativeLayout>
    <ProgressBar
        android:id="@+id/pb_async"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="30dp" />
    <TextView
        android:id="@+id/tv_async"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这里查看加载进度"
        android:textColor="@color/black"
        android:textSize="17sp" />
</LinearLayout>

二、异步服务IntentService

服务虽然在后台运行,但它跟活动一样都在主线程中,如果后台运行的服务堵塞,用户界面就会卡着不动,俗称死机,因此我们可以使用Android封装好的异步服务IntentService有以下两个好处

1:免去复杂的消息通信流程

2:处理完成后无须手工停止服务,开发者可集中经理编写业务逻辑

开发者在定义异步服务时要注意以下四点

1:增加一个构造方法 并分配内部线程的唯一名称

2:onStartCommand方法要调用父类

3:耗时处理的业务代码要写在onHandlerIntent方法中

4:异步服务只能通过普通方式启停 不能通过绑定方式启停

效果如下 异步服务不影响主界面的操作

代码如下

Java类

package com.example.chapter11;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter11.service.AsyncService;
import com.example.chapter11.util.DateUtil;
@SuppressLint("SetTextI18n")
public class IntentServiceActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView tv_intent;
    private Handler mHandler = new Handler(); // 声明一个处理器对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);
        tv_intent = findViewById(R.id.tv_intent);
        findViewById(R.id.btn_intent).setOnClickListener(this);
        mHandler.postDelayed(mService, 100); // 延迟100毫秒后启动异步任务
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_intent) {
            tv_intent.setText(DateUtil.getNowTime() + " 您轻轻点了一下下(异步服务正在运行,不影响您在界面操作)");
        }
    }
    private Runnable mService = new Runnable() {
        @Override
        public void run() {
            // 构建通往异步服务的意图
            Intent intent = new Intent(IntentServiceActivity.this, AsyncService.class);
            startService(intent); // 启动意图设定的异步服务
        }
    };
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button
        android:id="@+id/btn_intent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="5dp"
        android:text="点我看看有没有反应"
        android:textColor="@color/black"
        android:textSize="17sp" />
    <TextView
        android:id="@+id/tv_intent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:text="这里查看点击结果"
        android:textColor="@color/black"
        android:textSize="17sp" />
</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
3月前
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
238 1
|
22天前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
1月前
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
227 2
|
2月前
|
XML IDE 开发工具
🔧Android Studio高级技巧大公开!效率翻倍,编码不再枯燥无味!🛠️
【9月更文挑战第11天】在软件开发领域,Android Studio凭借其强大的功能成为Android开发者的首选IDE。本文将揭示一些提升开发效率的高级技巧,包括自定义代码模板、重构工具、高级调试技巧及多模块架构。通过对比传统方法,这些技巧不仅能简化编码流程,还能显著提高生产力。例如,自定义模板可一键插入常用代码块;重构工具能智能分析并安全执行代码更改;高级调试技巧如条件断点有助于快速定位问题;多模块架构则提升了大型项目的可维护性和团队协作效率。掌握这些技巧,将使你的开发之旅更加高效与愉悦。
64 5
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
55 1
|
3月前
|
开发工具 uml git
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
本文分享了下载AOSP源码的方法,包括如何使用repo工具和处理常见的repo sync错误,以及配置Python环境以确保顺利同步特定版本的AOSP代码。
428 0
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
|
3月前
|
开发工具 Android开发 git
全志H713 Android 11 :给AOSP源码,新增一个Product
本文介绍了在全志H713 Android 11平台上新增名为myboard的产品的步骤,包括创建新的device目录、编辑配置文件、新增内核配置、记录差异列表以及编译kernel和Android系统的详细过程。
108 0
|
存储 缓存 安全
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
515 0
|
6月前
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
199 1
|
6月前
|
Android开发 网络架构
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
892 1

热门文章

最新文章