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>

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

相关文章
|
2月前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
118 3
|
1月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
239 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
209 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
4月前
|
数据采集 弹性计算 运维
打造您的专属赛事神经中枢 | 专业比分网/APP开发服务
我们为体育俱乐部、媒体、社区等打造专属实时比分平台,覆盖全球赛事,支持多终端访问,提供毫秒级更新、精准数据与个性化推送,助力高效观赛体验。
|
1月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
528 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
491 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
2月前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
232 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
2月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
110 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
1月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
122 0
|
2月前
|
XML 存储 Java
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
104 3
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡

热门文章

最新文章