Android异步和线程

代码仓库:https://github.com/MADMAX110/Starbuzz

Android应用打开数据库时首先要搜索数据库文件,如果没有找到数据库文件就要创建一个空的数据库。然后它要运行所有SQL命令,在数据库中创建数据库表和需要的所有初始数据。最后还要执行一些查询从数据库得到数据。

线程合作让生活更美好

访问一个很慢的数据库会让你的应用看起来好像没有响应。
线程主要有三种:
1、主事件线程
2、呈现线程
3、你创建的所有其他线程
如果你不细心,应用几乎所有的工作都可能在主事件线程中完成,因为这个线程运行你的事件方法,如果把数据库代码放在onCreate方法中,主事件线程就会忙于与数据库交互,而不会迅速应对来自屏幕或其他应用的事件。
如果你的数据库代码要花很长时间,用户就会觉得自己被忽略,或者担心应用是否崩溃了。
所以这里的技巧时将数据库代码从主事件线程移出来,在后台的一个定制线程中运行。

AsyncTask完成异步任务

AsyncTask类允许你在后台完成操作。这些操作运行结束时,就可以在主事件线程中更新视图。
如果任务是重复的,甚至可以利用这个类发布任务运行的进度。
要创建AsyncTask,需要扩展AsyncTask类,并实现它的doInBackground方法。这个方法中的代码会在后台线程中运行,所以把数据库代码放在这里非常合适。AsyncTask类还有一个onPreExecute方法,这个方法在doInBackground之后运行。如果需要发布任务进度还可以使用一个onProgressUpdate方法。

private class MyAsyncTask extends AsyncTask{//可选,在后台运行的代码之前运行@Overrideprotected void onPreExecute() {super.onPreExecute();}//必须实现这个方法@Overrideprotected Object doInBackground(Object[] objects) {return null;}//允许你发布在后台运行的代码的进度@Overrideprotected void onProgressUpdate(Object[] values) {super.onProgressUpdate(values);}//在后台中的代码结束运行@Overrideprotected void onPostExecute(Object o) {super.onPostExecute(o);}}

onPreExecute方法

这个方法会在后台任务开始之前调用,用来建立任务。
onPreExecute方法在主事件线程调用,所以它可以访问用户界面中的视图。
在这里使用onPreExecute方法得到favorite复选框的值,把它放在drinkValues ContentValues对象中。
这是因为我们需要访问这个复选框视图才能得到它的值,而且这个工作必须在运行数据库代码之前完成。
我们要在这个方法之外使用另一个属性表示drinkValues ContentValues对象,使得这个类的其他方法也能访问这个ContentValues对象。

    private class UpdateDrinkTask extends AsyncTask<Integer, Void, Boolean>{private ContentValues drinkValues;protected void onPreExecute(){CheckBox favorite = (CheckBox) findViewById(R.id.favorite);drinkValues = new ContentValues();drinkValues.put("FAVORITE", favorite.isChecked());}}

doInBackground方法

        @Overrideprotected Boolean doInBackground(Integer[] drinks) {int drinkId = drinks[0];SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(DrinkActivity.this);try {SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();db.update("DRINK",drinkValues,"_id = ?",new String[] {Integer.toString(drinkId)});db.close();return true;}catch (SQLiteException e){return false;}}

onProgressUpdate方法

该方法在主事件线程调用,所以可以访问用户界面中的视图。可以使用这个方法更新屏幕上的视图向用户显示进度。要定义这个方法接受什么类型的参数。
如果由doInBackground方法调用publishProgress,就会运行onProgressUpdate方法,如下所示

        protected Boolean doInBackground(Integer[] count) {for (int i = 0; i < count; ++i){publishProgress(i);}}@Overrideprotected void onProgressUpdate(Integer... progress) {super.onProgressUpdate(progress[0]);}

onPostExecute方法

后台任务完成后调用onPostExecute()方法。它在主事件线程中调用,所以可以访问用户界面中的视图。可以使用这个方法为用户呈现任务的结果。要把doInBackground方法的结果传入onPostExecute方法,所以它的参数必须与doInBackground的返回类型一致

我们要使用onPostExecute方法检查doInBackground方法中的数据库代码是否成功运行。如果没有,就要向用户显示一个消息。这个工作在onPostExecute方法中完成,因为这个方法可以更新用户界面。doInBackground方法在后台线程中运行,所以不能更新视图。

    protected void onPostExecute(Boolean success) {if (!success) {Toast toast = Toast.makeText(DrinkActivity.this, "Darabase unavailable", Toast.LENGTH_SHORT);toast.show();}}

AsyncTask类

AsyncTask是一个抽象类,它定义了三个泛型参数:Params、Progress和Result。这三个参数在创建AsyncTask的子类并实现其方法时使用,以便更好地处理异步任务。
Params:这个参数类型是在任务开始执行时传递给AsyncTask的。具体传递的内容根据任务的需要而定,例如,可能是要加载的图片的URL,或者是需要从网络上获取数据的特定字段名称等。
Progress:这个参数类型用于异步任务执行过程中的进度更新。当任务执行过程中需要更新进度时,可以在任务线程中调用publishProgress()方法,传递当前的进度值,然后在主线程中通过重写onProgressUpdate(Progress…)方法来接收并处理这些进度值。
Result:这个参数类型是在异步任务执行完成后返回的结果。当任务执行完毕后,可以在任务线程中调用onPostExecute(Result result)方法,传递计算得到的结果,然后在主线程中通过重写此方法来接收并处理这些结果。
这三个参数在AsyncTask中是非常重要的,它们使得异步任务的执行过程变得更加清晰、有条理。

完整的DrinkActivity

package com.hfad.starbuzz;import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;public class DrinkActivity extends AppCompatActivity {public static final String EXTRA_DRINKID = "drinkId";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_drink);int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);try {SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();Cursor cursor = db.query("DRINK",new String[]{"NAME", "DESCRIPTION", "IMAGE_RESOURCE_ID", "FAVORITE"},"_id = ?",new String[] {Integer.toString(drinkId)},null, null, null);if (cursor.moveToFirst()) {String nameText = cursor.getString(0);String descriptionText = cursor.getString(1);int photoId = cursor.getInt(2);boolean isFavorite = (cursor.getInt(3) == 1);TextView name = (TextView) findViewById(R.id.name);name.setText(nameText);TextView description = (TextView) findViewById(R.id.description);description.setText(descriptionText);ImageView photo = (ImageView) findViewById(R.id.photo);photo.setImageResource(photoId);photo.setContentDescription(nameText);CheckBox favorite = (CheckBox) findViewById(R.id.favorite);favorite.setChecked(isFavorite);}cursor.close();db.close();}catch (SQLException e){Toast toast = Toast.makeText(this,"Database unavailable",Toast.LENGTH_SHORT);toast.show();}}public void onFavoriteClicked(View view){int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);CheckBox favorite = (CheckBox) findViewById(R.id.favorite);ContentValues drinkValues = new ContentValues();drinkValues.put("FAVORITE", favorite.isChecked());SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);try{SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();db.update("DRINK",drinkValues,"_id = ?",new String[] {Integer.toString(drinkId)});db.close();}catch(SQLiteException e) {Toast toast = Toast.makeText(this, "Database unavailable", Toast.LENGTH_SHORT);toast.show();}}private class UpdateDrinkTask extends AsyncTask<Integer, Void, Boolean> {private ContentValues drinkValues;protected void onPreExecute(){CheckBox favorite = (CheckBox) findViewById(R.id.favorite);drinkValues = new ContentValues();drinkValues.put("FAVORITE", favorite.isChecked());}@Overrideprotected Boolean doInBackground(Integer[] drinks) {int drinkId = drinks[0];SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(DrinkActivity.this);try {SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();db.update("DRINK",drinkValues,"_id = ?",new String[] {Integer.toString(drinkId)});db.close();return true;}catch (SQLiteException e){return false;}}}protected void onPostExecute(Boolean success) {if (!success) {Toast toast = Toast.makeText(DrinkActivity.this, "Darabase unavailable", Toast.LENGTH_SHORT);toast.show();}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rust变量

一 、变量定义 &#xff08;一&#xff09;语法格式 使用let关键字定义变量 let varname: type value; 如&#xff0c;let a: i32 78;也可以不显式指定类型 let varname value; 如&#xff0c;let a 78;一些例子 1.布尔 let t true; let f: bool false;2.整数 let a …

合宙Air780e+luatos+腾讯云物联网平台完成设备通信与控制(属性上报+4G远程点灯)

1.腾讯云物联网平台 首先需要在腾讯云物联网平台创建产品、创建设备、定义设备属性和行为&#xff0c;例如&#xff1a; &#xff08;1&#xff09;创建产品 &#xff08;2&#xff09;定义设备属性和行为 &#xff08;3&#xff09;创建设备 &#xff08;4&#xff09;准备参…

ctrl+d和ctrl+c的区别

CtrlD和CtrlC都是常用的键盘快捷键&#xff0c;但它们的功能不同。 CtrlD 在不同的操作系统和应用程序中可以有不同的功能。在Unix/Linux系统的命令行终端中&#xff0c;CtrlD的作用是发送EOF&#xff08;End of File&#xff09;信号&#xff0c;表示输入结束。在Windows系统中…

【高阶数据结构】图详解第一篇:图的基本概念及其存储结构(邻接矩阵和邻接表)

文章目录 1. 图的基本概念1.1 什么是图1.2 有向图和无向图1.3 完全图1.4 邻接顶点1.5 顶点的度1.6 路径1.7 路径长度1.8 简单路径与回路1.9 子图1.10 连通图1.11 强连通图1.12 生成树 2. 图的存储结构2.1 邻接矩阵2.2 邻接矩阵代码实现结构定义构造函数添加边打印图测试 2.3 邻…

ToBeWritten之改进威胁猎杀:自动化关键角色与成功沟通经验

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…

10款录屏软分析与选择使用,只看这篇文章就轻松搞定所有,高清4K无水印录屏,博主UP主轻松选择

录屏软件整理 如下为录屏软件&#xff0c;通过思维导图展示分析介绍&#xff1a; https://www.drawon.cn/template/details/6522bd5e0dad9029a0b528e1 如下为整理的录屏软件列表 名称产地价格支持的平台下载地址说明OBS国外免费开源windows/linux/machttps://obsproject.co…

linux 笔记:远程服务器登录jupyter notebook

1 生成jupyter notebook 配置文件&#xff08;服务器端&#xff09; jupyter notebook --generate-config #Writing default config to: /home/shuailiu/.jupyter/jupyter_notebook_config.py2 Ipython中设置密码&#xff08;服务器端&#xff09; 3 修改jupyter 配置文件&…

汇编语言是怎么一回事?

汇编语言基础 汇编指令和机器码的区别 数据的表示 各类汇编指令 数据传送和算法运算 位运算 条件分支指令 函数调用 字符串处理 流水线和指令调度 流水线实现指令级并行 编译器指令调度 CPU乱序与投机执行 汇编器将汇编语言翻译成 CPU 可以执行的机器码&#xff0c…

强烈推荐这5款功能强大的小软件

​ 今日的栽种&#xff0c;明日的果实&#xff0c;今天继续分享五个功能强大的小软件。 1.文本编辑——IDM UltraEdit ​ IDM UltraEdit是一款功能强大的文本编辑器&#xff0c;它支持多种编程语言和文件格式&#xff0c;可以处理大型文件&#xff0c;进行代码折叠&#xff0…

reactjs开发环境搭建

Reactjs是一个前端web页面应用开发框架工具集&#xff0c;其支持前端构建页面以及后端构建页面两种常用的开发场景&#xff0c;其中&#xff0c;支持reactjs的开发框架包括next.js、remix、gatsby以及其他&#xff0c;本文主要描述next.js开发环境的搭建&#xff0c;next.js是一…

c++中的map和set

文章目录 1. 关联式容器2. 键值对3. 树形结构的关联式容器3.1 set3.1.1 set的介绍3.1.2 set的使用 3.2 map3.2.1 map的介绍3.2.2 map的使用 3.3 multiset3.3.1 multiset的介绍3.3.2 multiset的使用 3.4 multimap3.4.1 multimap的介绍3.4.2 multimap的使用 1. 关联式容器 在初阶…

java socket实现代理Android App

实现逻辑就是转发请求和响应。 核心代码 // 启动代理服务器private void startProxyServer() {new Thread(new ProxyServer()).start();}// 代理服务器static class ProxyServer implements Runnable {Overridepublic void run() {try {// 监听指定的端口int port 8098; //一…

CSS 实现:常见布局

1 设备与视口 设备屏幕尺寸是指屏幕的对角线长度。像素是计算机屏幕能显示一种特定颜色的最小区域&#xff0c;分为设备像素和逻辑像素。 在 Apple 的视网膜屏&#xff08;Retina&#xff09;中&#xff0c;默认每 4 个设备像素为一组&#xff0c;渲染出普通屏幕中一个像素显示…

Elasticsearch:如何从 Elasticsearch 集群中删除数据节点

Elasticsearch 集群通常包含多个节点&#xff0c;并且可能存在需要从集群中删除节点的情况。 应谨慎执行此过程&#xff0c;以确保数据的完整性和可用性。 在本文中&#xff0c;我们将引导你完成从 Elasticsearch 集群安全删除节点的步骤。 确保集群是绿色的 在尝试从 Elastic…

【数字化转型】10大数字化转型能力成熟度模型03

一、前言 数字化转型是数据化能力建设的目标和价值,作为一个新兴的课题,目前为止并未出现一个统一的数字化转型成熟度模型。不同的企业和机构,根据自身的发展和认知,推出了自己的企业级或者准行业级标准。这些标准具有很强的参考意义,作者收集和整理了相关的标准和规范,整…

MongoTemplate | 多条件查询

MongoTemplate查询 Resource private MongoTemplate mongoTemplate;public <T> List<T> getDataList(String param1, Long param2, Class<T> clazz) {// 构建queryQuery query constructQuery(param1, param2);// 查询return mongoTemplate.find(query, cl…

[leetcode 哈希表] 2034. 股票价格波动 M

给你一支股票价格的数据流。数据流中每一条记录包含一个 时间戳 和该时间点股票对应的 价格 。 不巧的是&#xff0c;由于股票市场内在的波动性&#xff0c;股票价格记录可能不是按时间顺序到来的。某些情况下&#xff0c;有的记录可能是错的。如果两个有相同时间戳的记录出现…

HTML5+CSS3+JS小实例:鼠标滚轮水平滚动

实例:鼠标滚轮水平滚动 技术栈:HTML+CSS+JS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="…

《游戏编程模式》学习笔记(十二)类型对象 Type Object

定义 定义类型对象类和有类型的对象类。每个类型对象实例代表一种不同的逻辑类型。 每种有类型的对象保存对描述它类型的类型对象的引用。 定义往往不是人能看懂的&#xff0c;我们需要例子才能够理解。 举例 假设你要为一款游戏制作一些怪物敌人。这些敌人有不同的血量及攻…

MariaDB 修改用户远程登录

今天修改MariaDB数据库用户的Host时出现错误&#xff1a; ERROR 1356 (HY000): View ‘mysql.user’ references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them 我的步骤如下&#xff1a; 1.登陆 2.use mysql; 3.执行…