Android中的进程与多线程的讲解(Handler和AsyncTask)

2023-11-20

Hello EveryBody,又到了我们相聚的时间了,今天要总结的东西现在有点迫不及待了,因为在实际的应用中如果用不到它,我们就不能再听歌的同时发送信息,其实大家应该都知道了,今天的主角就是进程与多线程,好了,其他的不多说,直接进入正题吧。


一.Android进程的分类:

(1)前台进程:即与用户正在交互的Activity或者Activity用到的Service等,如果系统内存不足时前台进程是最后被杀死的;

(2)可见进程:可以是处于暂停状态(onPause)的Activity或者绑定在其上的Service,即被用户可见,但由于失去了焦点而不能与用户交互;

(3)服务进程:其中运行着使用startService方法启动的Service,虽然不被用户可见,但是却是用户关系的,例如用户正在非音乐界面听的音乐或者正在非下载页面自己下载的文件等;当系统要用空间运行前两者进程时才会被终止;

(4)后台进程:其中运行着执行onStop方法而停止的程序,但是却不是用户当前关心的,例如后台挂着的QQ,这样的进程系统一旦没有内存就首先被杀死;

(5)空进程:不包含任何应用程序的程序组件的进程,这样的进程系统是一般不会让他存在的;


二.进程与多线程的深入

1.由于单线程而导致的ANR错误:

   ANR错误(Application Not Responding),指主UI进程被阻塞超过5秒钟而出现的错误,它会终止程序的正常运行,我们要避免它 ,而产生ANR错误的原因就是:单线程。

例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package  com.example.l0902_anr;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.TextView;
public  class  MainActivity  extends  Activity {
private  Button btn;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn=(Button) findViewById(R.id.btn);
         btn.setOnClickListener( new  OnClickListener() {
                                                                                                                                                                                                                                                                                                                                                                                                                                                     
             @Override
             public  void  onClick(View v) {
                 int  count= 0 ;
                 while (count< 1000 ){
                     count++;
                     try  {
                         Thread.sleep( 1000 );
                     catch  (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }
         });
                                                                                                                                                                                                                                                                                                                                                                                                                                                 
     }
}

运行效果如下:


   OK,上面的程序出问题的原因是单线程,那么我们可以再创建一个线程去处理耗时操作,就不会阻碍主UI的操作了:

   改动上面的程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package  com.example.l0902_anr;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
public  class  MainActivity  extends  Activity {
private  Button btn,btn_stop;
private  Thread thread;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn=(Button) findViewById(R.id.btn);
         btn_stop=(Button) findViewById(R.id.button1);
         btn.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 thread= new  Thread( new  Runnable() {
                     @Override
                     public  void  run() {
                         int  count= 0 ;
                         while (count< 1000 ){
                             count++;
                             try  {
                                 Thread.sleep( 1000 );
                             catch  (InterruptedException e) {
                                 e.printStackTrace();
                             }
                             System.out.println(count);
                         }
                     }
                 });
                 thread.start(); //启动线程
             }
         });
         btn_stop.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 thread.stop(); //停止线程
             }
         });
     }
}

   运行效果如下:


   代码写到这里,ANR错误就解决了,但是又出现一个新的问题,如果我想把利用新的线程来更新主UI线程,可以不可以呢,好吧,我们用上面的程序试一试,加一个TextView来接收新的线程中自增的数据,看看是否能实现:

   程序修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package  com.example.l0902_anr;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.TextView;
public  class  MainActivity  extends  Activity {
private  Button btn;
private  TextView tv;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn=(Button) findViewById(R.id.btn);
         tv=(TextView) findViewById(R.id.tv);
         btn.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 new  Thread( new  Runnable() {
                     @Override
                     public  void  run() {
                         int  count= 0 ;
                         while (count< 1000 ){
                             count++;
                             tv.setText(count+ "" ); //试图更新主UI线程
                             try  {
                                 Thread.sleep( 1000 );
                             catch  (InterruptedException e) {
                                 e.printStackTrace();
                             }
                         }
                     }
                 }).start(); //启动线程
             }
         });
     }
}


   运行效果如下:


   我们可以看到程序被意外终止了,那么说明其他线程是不能更改主UI的数据的,除非...除非我们往下看...


2.Android线程之间的通信——Handler

   其实,Android线程之间的通信不只是Handler,还需要Message,MessageQueue,Looper的相互使用,Android线程通信模型如下:

(1)Message:即要传递的消息;

(2)MessageQueue:存放消息的队列;

(3)Looper:用于创建MessageQueue以及循环使用其中的Message;

(4)Handler:用于消息的传递了;

好了,我们直接看下面的例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package  com.example.l0902_handler;
import  android.annotation.SuppressLint;
import  android.app.Activity;
import  android.os.Bundle;
import  android.os.Handler;
import  android.os.Message;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.TextView;
public  class  MainActivity  extends  Activity {
     private  Button btn_start,btn_stop;
     private  TextView tv;
     private  int  i= 0 ;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn_start=(Button) findViewById(R.id.button1);
         btn_stop=(Button) findViewById(R.id.button2);
         tv=(TextView) findViewById(R.id.textView1);
         btn_start.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 //开始发送消息
                 handler.post(runnabl);
             }
         });
         btn_stop.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 //停止发送消息
                 handler.removeCallbacks(runnabl);
             }
         });
     }
     //创建新的线程
     private  Runnable runnabl= new  Runnable() {
         @Override
         public  void  run() {
             i++;
             //使用Message封装非UI线程的消息
             Message m= new  Message();
             //使用Message的arg1属性或者arg2属性传递int类型的消息效率高
             m.arg1=i;
             //使用Handler发送消息
             handler.sendMessage(m);
         }
     };
     @SuppressLint ( "HandlerLeak" )
     private  Handler handler= new  Handler(){
         public  void  handleMessage(Message m){
             System.out.println(m.arg1);
             String str=m.arg1+ "" ;
             //注意:一定一定要记得TextView是String类型哦
             tv.setText(str);
             handler.post(runnabl);
         }
     };
}

   运行结果如下:

   看到了吧,主UI的数据是不是更新了呢,很是神奇吧,这就是线程之间的通信了。

   接下来我们要继续讲一个线程通信的机制。。。


3.简化多线程通信开发的——AsyncTask

   我们直接用例子说明AsyncTask的使用吧:

(1)我们同样也先写一个类似上面的ANR错误的卡屏的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package  com.example.l0902_myasynctask;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
public  class  MainActivity  extends  Activity {
     private  Button btn1,btn2;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn1=(Button) findViewById(R.id.button1);
         btn2=(Button) findViewById(R.id.button2);
         btn1.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 try  {
                     //超过5秒了,其实就和前面的例子一样了(ANR错误)
                     Thread.sleep( 7000 );
                 catch  (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         });
         btn2.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 System.out.println( "Hello To EveryOne" );
             }
         });
     }
}

   运行效果如下:


   如果把上面等待的时间改为5以内,则就是典型的卡屏的例子了,试试看吧:

初始界面:


点击下面的按钮:


点击上面的按钮:此时就卡住了,屏幕什么都干不了了


卡屏期间点击了多少下下边的按钮,5秒之后都会显示出来:

上面就是经典的卡屏的例子,怎么解决呢?当然是:AsyncTask了

(2)使用AsyncTask创建后台进程,解决卡屏问题:

代码如下:

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package  com.example.l0902_myasynctask;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
public  class  MainActivity  extends  Activity {
     private  Button btn1,btn2;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn1=(Button) findViewById(R.id.button1);
         btn2=(Button) findViewById(R.id.button2);
         btn1.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 //创建AsyncTask并执行
                 new  MyAsyncTask().execute();
             }
         });
         btn2.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 System.out.println( "Hello To EveryOne" );
             }
         });
     }
}

MyAsyncTask.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  com.example.l0902_myasynctask;
import  android.os.AsyncTask;
/**
  * 在后台创建线程,不会出现卡屏现象
  * @author asus
  */
public  class  MyAsyncTask  extends  AsyncTask<Void, Void, String>{
     //核心方法,在后台启动一个线程
     @Override
     protected  String doInVoid...  params) {
         try  {
             Thread.sleep( 5000 );
         catch  (InterruptedException e) {
             e.printStackTrace();
         }
         return  null ;
     }
}

运行效果我们就不再给出了,描述一下就可以了,即无论我们是否按卡屏按钮,执行按钮都能正常输出,这正是因为AsyncTask创建了一个后台进程来处理耗时功能,不影响主UI的正常功能的处理。


(3)最后总结一个使用AsyncTask的例子——下载滚动条的进度:

MainActivity.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package  com.example.l0902_usinganysc;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.ProgressBar;
import  android.widget.TextView;
public  class  MainActivity  extends  Activity {
     private  Button btn;
     private  ProgressBar bar;
     private  TextView tv;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         btn=(Button) findViewById(R.id.button1);
         bar=(ProgressBar) findViewById(R.id.progressBar1);
         tv=(TextView) findViewById(R.id.textView1);
         tv.setText( "开始下载" );
         btn.setOnClickListener( new  OnClickListener() {
                                                        
             @Override
             public  void  onClick(View v) {
                 MyAsyncTask my= new  MyAsyncTask(tv, bar);
                 my.execute( "" , "i=" , "打开文件" ); //启动方法
             }
         });
     }
}

MyAsyncTask.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package  com.example.l0902_usinganysc;
import  android.os.AsyncTask;
import  android.widget.ProgressBar;
import  android.widget.TextView;
/**
  * 总结:参数相关
  * @author asus
  */
public  class  MyAsyncTask  extends  AsyncTask<String, Integer, String>{
     private  ProgressBar bar;
     private  TextView tv;
     //构造方法,初始化ProgressBar和TextView
     public  MyAsyncTask(TextView tv,ProgressBar bar){
         this .bar=bar;
         this .tv=tv;
     }
     /*
      * 这个方法的参数不能改,其返回类型与第三个参数一致,其参数与第一个参数类型一致
      * (non-Javadoc)
      * @see android.os.AsyncTask#doInParams[])
       */
     @Override
     protected String doInString...  params) {//可变参数
         String p1=params[1];
         String p2=params[2];
         int i=1;
         for(i=1;i<=100;i++){
             try {
                 Thread.sleep(100);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             publishProgress(i);
         }
         return p1+i+p2;//也作为下一个方法的参数
     }
     /*
      * 当异步结束时触发此方法,其参数类型与第三个参数类型一致
      * (non-Javadoc)
      * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
      */
     @Override
     protected void onPostExecute(String result) {
         if(result!=null){
             tv.setText("下载完成"/*+result*/);
         }
         super.onPostExecute(result);
     }
     /*
      * 当异步开始的时候触发
      * (non-Javadoc)
      * @see android.os.AsyncTask#onPreExecute()
      */
     @Override
     protected void onPreExecute() {
         System.out.println("异步开始");
         tv.setText("开始下载");
         super.onPreExecute();
     }
     /*
      * 正在处理的时候触发,与主UI线程交互,其参数与第二个参数一致
      * (non-Javadoc)
      * @see android.os.AsyncTask#onProgressUpdate(Progress[])
      */
     @Override
     protected  void  onProgressUpdate(Integer... values) { //第二个可变参数,由上面的publishProgress方法的参数决定
         bar.setProgress(values[ 0 ]);
         tv.setText(values[ 0 ]+ "%" ); //可变参数就是这么用的,values[1]表示publishProgress的第二个参数
         super .onProgressUpdate(values);
     }
}

运行效果如下:






from:http://wangzhaoli.blog.51cto.com/7607113/1287545



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中的进程与多线程的讲解(Handler和AsyncTask) 的相关文章

  • grep的用法

    命令介绍 Linux系统中grep命令是一种强大的文本搜索工具 它能使用正则表达式搜索文本 并把匹配的行打印出来 匹配到的标红grep全称是Global Regular Expression Print 表示全局正则表达式版本 它的使用权限
  • khv是什么虚拟服务器,服务器虚拟化vSphere4 vs Hyper-V R2,选择谁?

    目前在X86服务器平台上做虚拟化 是非常热的 目前主要有两个选择 VMWare的vSphere4和微软的Hyper V R2 VMWare非常成熟 企业级用户很多 但价格不便宜 按照CPU数量和版本收费 Hyper V R2很便宜 但出来的
  • 检查内存泄露

    自己编写的视频处理程序出现了一个问题 每帧的运行时间随着运行时间在不断增长 很大可能是出现了内存泄露 于是学习了一些查看内存泄露的方法 做了两种尝试 一是VS自带的DEBUG下的检测 view pl html view plain copy
  • Windows上让Qt5 QCamera响应UVC摄像头硬件按钮拍图

    QCamera相机类提供了一些基本的功能 包括拍照和录制功能 Windows上不支持录制视频 但也有很多接口是没有封装的 比如有些UVC摄像头有物理按键 可以进行拍图等操作 但是QCamera没法响应硬件按钮的拍图操作 网络上的相关代码都是
  • RC-u4 相对论大师(bfs求解指定路径)

    PTA 程序设计类实验辅助教学平台 题解 bfs可以求解从根节点到叶子节点的指定路径 这里的vis 不是为了防止访问到父节点 更多的是为了缩小路径长度 mpp和mp的映射也很巧妙 开始我用的还是map
  • [从零开始学习FPGA编程-38]:进阶篇 -语法-函数与任务

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 第1章 什么是函数Function 1 1 什么是函数 1 2 函
  • 【JAVA】输入:Scaner

    一 语法 1 导入 import java util Scanner 2 创建对象 Scanner scanner new Scanner System in 3 创建变量 int x scanner nextInt next系列 next
  • 服务器运维基础指南

    服务器运维基础指南 作为一个开发人员 对于服务器的操作不可避免 最常用的操作就是部署应用到服务器 及在生产 测试环境通过查看日志排查问题 一般服务器都是linux操作系统并且是无图形界面的 所以进行任何操作都是通过命令行 由于从新一代程序员
  • Android 中的AIDL 和 binder机制

    一 Binder 1 线程间通信Handler Handler和Binder是Android通信的两大支柱 Handler是线程间通信的基础 一个App的运行一定是多个线程相互协作的过程 特别是Android子线程不能更新UI界面的限制使得
  • 微信使用精准位置 wx.getLocation步骤

    微信小程序 gt 开发设置 gt 接口设置 gt 开通 wx getLocation 申请理由 应当前业务涉及周边服务推荐需要 需获取用户地理位置信息 调试基础库 2 24 4 在app json中添加 requiredPrivateInf
  • VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题...

    VC9编译的程序在没有装过VC9 确切的说是 Net Framework3 5 的机器上运行时 如果提示 由于应用程序配置不正确 应用程序未能启动 重新安装应用程序可能会纠正这个问题 这个错误 那么就说明该程序动态链接了VC9的运行时库 如
  • Java 实现 SCP 携带密码拷贝文件

    package com miracle luna scp import org apache sshd client SshClient import org apache sshd client session ClientSession
  • 线上阿里云短信盗刷问题实录

    背景 营销系统中有定时任务处理将待支付订单变更为已取消 执行时间五分钟一次 业务执行处理异常会发送短信给相关开发人员进行短信提醒 从下午一点二十五开始 开发人员间隔五分钟就会收到业务执行异常的短信提醒 最初因为测试或是正式环境中确实有异常的
  • 国产化系统下操作PDF

    本文围绕使用netcore 跨平台在国产系统 麒麟和统信 操作PDF 首先netcore 需要第三方dll 在Nuget里搜索itextsharp 选择图片中 安装即可 版本写了 itextsharp 是4 16 比较靠后 但是基本功能都有
  • Android反调试方法总结以及源码实现之检测篇(一)

    好久没有更新博客了 主要是忙项目的事 今日总结一下在Android中常遇到的反调试方法 一来帮助需要之人 二来加深自己的理解 反调试在代码保护中扮演着很重要的角色 虽然不能完全阻止攻击者 但是还是能加大攻击者的时间成本 一般与加壳结合使用

随机推荐

  • 手写SSH2服务器连接池

    初衷 在工作中遇到一个要与远程服务器建立连接并进行上传 下载的场景 所以在课余就试着写了一个ssh2服务器连接池的小demo 仅供参考 欢迎指正 目录概要 pom文件引入依赖
  • 内网信息收集(一)

    内网信息收集 收集本机信息 拿到一台服务器权限需要收集的信息 包括操作系统 IP 是否存在杀毒软件 打过的补丁等信息 查询网络配置信息 ipconfig all Linux下使用ifconfig 查询用户列表 net user 查看本机列表
  • 《重构的时机和方法》一本值得程序员都认真读的书

    写在前面 重构的时机和方法 是一本关于软件开发中重构技术的书籍 它以独特的风格和内容优势 为读者提供了全面而易于理解的指导 帮助他们在实际项目中应用重构技术 提高代码质量和开发效率 这本书由两个不同风格的部分组成 旨在满足不同读者群体的需求
  • 预训练模型与微调

    前言 预训练模型已经火了这么久了 但作为菜本菜的我却还在用lstm 在生成任务上与同门学长用的预训练模型相比 效果差的比较明显 所以 我决定走上预训练的不归路 以下分享我的学习过程 了解模型 小说故事生成模型 万事开头难 上视频 视频我喜欢
  • 汕头大学医学院物理与计算机教研室,药剂学教研室 - 汕头大学医学院 Shantou University Medical College...

    凌凯 男 中国医学科学院 北京协和医学院 清华大学医学部 生物医学工程 医学博士 副研究员 从事生物纳米检测新技术的研究与新型纳米肿瘤药物及疗法的研究 以第一作者和通讯作者发表SCI论文8篇 以项目负责人承担国家自然科学基金青年基金项目 广
  • spring过滤器、拦截器

    文章目录 一 二者对比 二 过滤器 过滤器的分类 过滤器的作用 过滤器的实现方式 三 拦截器 拦截器的实现方式 四 二者总结 一 二者对比 实现原理不同 过滤器是基于函数回调 拦截器是基于java的反射机制的 使用范围不同 过滤器依赖与se
  • 基于python图书馆管理系统和读者系统(附完整代码以及打包好的exe文件)

    摘要 本文基于python的图书馆管理系统和读者系统 实现了登录 注册 忘记密码 书籍查询 借阅 归还 修改等功能 通过csv文件将数据存储在本地 注册时采用了邮箱验证码 模拟了现实场景 全部源代码地址见文末 如果有其他奇思妙想或者bug欢
  • 【pytorch目标检测】创新之作:Fast R-CNN算法解读

    背景 2015年 提出了Fast RCNN算法 训练步骤实现端到端 CNN 基于VGG6 Fast R CNN是基于R CNN和SPPnets进行的改进 成果 训练速度比RCNN块9倍 测试速度快乐23倍 准确率68 4 SPPnets网络
  • Python实现PDF合并工具(含源码)

    在工作中 每个月都会要遇到报账的情况 在现如今很多都是使用电子发票 获得的电子发票很多都是PDF格式 偶尔也有图片格式的 而且还是一张发票一个pdf文档 在打印贴票时 就需要一个文档一个文档的打开打印 十分的不便捷 当然也可以使用某某PDF
  • Trello中的Scrum

    Trello的用户数量近期超越了1000万的大关 它正迅速成为各色敏捷团队中流行的工具 它的简洁及在Web 移动端优秀的体验 使它从众多更复杂的解决方案中脱颖而出 赢得了更多的团队 因为Trello完全不在意用户如何使用 所以导致用户在用它
  • Mysql 基础

    判断数据库是否存在 存在就删除 drop database if exists testdb 创建数据库表的操作 create database testdb 使用数据库 use testdb 判断创建的表是否存在 存在就删除 drop t
  • 2021年12月-电子学会青少年等级考试C语言(一级)真题与解析

    2021年12月软件编程 C语言 等级考试 一级 分数 100 题数 5 时间限制 1000 ms 内存限制 65536 kB 1 输出整数部分 题目描述 输入一个双精度浮点数 输出其整数部分 输入 一个双精度浮点数f 0 lt f lt
  • PMD规则开发实战:打造自己的代码质量检测工具

    PMD介绍 介绍 PMD 安装和配置 如何安装和配置 PMD 插件以在的项目中使用 IDEA中如何使用PMD插件 Java项目中如何使用PMD PMD规则开发介绍 介绍如何编写和使用自定义 PMD 规则 SonarQube如何集成PMD S
  • Java 数据输入

    数据输入 数据输入概述 Java 提供接口用于接受控制台输入的变量 并进行相应的操作 Scanner 使用的基本步骤 导包 import java util Scanner 导包的动作必须出现在类定义的上面 创建对象 Scanner sca
  • 网易资深安卓架构师:没想到一个Handler还有中高级几种问法,论程序员成长的正确姿势

    本专栏专注分享大型Bat面试知识 后续会持续更新 喜欢的话麻烦点击一个关注 面试官 组件化如何实现 组件化与插件化的差别在哪里 该怎么选型 心理分析 面试官从架构层次 了解求职者是否用过 模块化 组件化 和插件化 在过去经验有没有运用过这些
  • 【Spring Boot 初识丨三】starter

    上一篇讲了如何构建MAVEN项目 本篇来讲一讲 starter 依赖项 Spring Boot 初识 Spring Boot 初识丨一 入门实战 Spring Boot 初识丨二 maven Spring Boot 初识丨三 starter
  • 【Android Studio 创建module】

    一 如何创建模型 一个项目里边可以有多个module 每个module对应的都是一个独立的程序 选择File菜单 gt New gt New Module gt 填写Module名称 library 一直next直到finish 给Modu
  • 如何从零开始搭建公司自动化测试框架?

    搭建的自动化测试框架要包括API测试 UI测试 APP测试三类 以上三类其实可以简化为两类 那就是 1 接口自动化测试框架搭建 2 UI自动化测试框架搭建 没问题 安排 且是手把手教你如何搭建以上两类自动化测试框架 回到这篇主题 刷到这个问
  • linux c语言常见面试题及答案,Linux下C语言的几道经典面试题小结(分享)

    Linux下C语言的几道经典面试题小结 分享 本篇文章整理了几道Linux下C语言的经典面试题 相信对大家更好的理解Linux下的C语言会有很大的帮助 欢迎大家探讨指正 1 如果在Linux下使用GCC编译器执行下列程序 输出结果是什么 答
  • Android中的进程与多线程的讲解(Handler和AsyncTask)

    Hello EveryBody 又到了我们相聚的时间了 今天要总结的东西现在有点迫不及待了 因为在实际的应用中如果用不到它 我们就不能再听歌的同时发送信息 其实大家应该都知道了 今天的主角就是进程与多线程 好了 其他的不多说 直接进入正题吧