zoukankan      html  css  js  c++  java
  • Android基础新手教程——3.7 AnsyncTask异步任务

    Android基础新手教程——3.7 AnsyncTask异步任务

    标签(空格分隔): Android基础新手教程


    本节引言:

    本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask。我们通常是
    继承AsyncTask,然后在类中实现异步操作,然后将异步运行的进度。反馈给UI主线程~
    好吧,可能有些概念大家不懂,认为还是有必要解说下多线程的概念,那就先解释下一些概念性的东西吧!


    1.相关概念

    1)什么是多线程:

    答:先要了解这几个名称:应用程序,进程,线程。多线程!

    • 应用程序(Application):为了完毕特定任务,用某种语言编写的一组指令集合(一组静态代码)
    • 进程(Process) :运行中的程序。系统调度与资源分配的一个独立单位。操作系统会为每一个进程分配
      一段内存空间,程序的依次动态运行。经理代码载入 -> 运行 -> 运行完毕的完整过程!

    • 线程(Thread):比进程更小的运行单元,每一个进程可能有多条线程,线程须要放在一个进程中才干运行!
      线程是由程序负责管理的!

      。而进程则是由系统进行调度的!。!

    • 多线程概念(Multithreading):并行地运行多条指令,将CPU的时间片依照调度算法。分配给各个线程,实际上是分时运行的。仅仅是这个切换的时间非常短。用户感觉是同一时候而已!

    举个简单的样例:
    你挂着QQ,突然想去听歌,你须要把QQ关掉,然后再去启动XX播放器吗?答案是否定的,我们直接打开播放器
    放歌就好,QQ还在运行着,是吧!这就是简单的多线程~在实际开发中,也有这种样例,比方应用正在运行,
    发现新版本号了。想后台更新,这个时候一般我们会开辟出一条后台线程,用于下载新版本号的apk,可是这个时候
    我们还能够使用应用中的其它功能。这就是多线程的使用样例~

    2)同步与异步的概念:

    答: 同步:当我们运行某个功能时,在没有得到结果之前。这个调用就不能返回。简单点就是说必须
    等前一件事做完才干做下一件事。举个简单的样例:比方你啪啪啪,为了避免弄出人命,肯定要先戴好套套,
    然后再啪啪啪是吧~套套戴好 -> 然后啪啪啪,比方你没套套。那啪啪啪的操作就要等待了。直到你把
    套套买回来带上,这个时候就能够開始啪啪啪了~一个形象地样例。♪(^∇^*)
    异步:和同步则是相对的。当我们运行某个功能后,我们并不须要马上得到结果,我们额能够正常地
    做其它操作,这个功能能够在完毕后通知或者回调来告诉我们。还是上面那个后台下载的样例,后台下载,
    我们运行下载功能后,我们就无需去关心它的下载过程。当下载完毕后通知我们就能够了~

    3) Android为非常么要引入异步任务

    答:由于Android程序刚启动时。会同一时候启动一个相应的主线程(Main Thread),这个主线程主要负责处理
    与UI相关的事件!有时我们也把他称作UI线程!而在Android App时我们必须遵守这个单线程模型的规则:
    Android UI操作并非线程安全的而且这些操作都须要在UI线程中运行!


    假如我们在非UI线程中,比方在主线程中new Thread()另外开辟一个线程,然后直接在里面改动UI控件的值。
    此时会抛出下述异常:
    android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views
    另外。另一点。假设我们把耗时的操作都放在UI线程中的话,假设UI线程超过5s没有响应用于请求。那么
    这个时候会引发ANR(Application Not Responding)异常,就是应用无响应~
    最后另一点就是:Android 4.0后禁止在UI线程中运行网络操作~不然会报:
    android.os.NetworkOnMainThreadException

    以上的种种原因都说明了Android引入异步任务的意义,当然实现异步也不能够不用到我们本节解说
    的AsyncTask。我们能够自己开辟一个线程,完毕相关操作后。通过下述两种方法进行UI更新:

    1. 前面我们学的Handler。我们在Handler里写好UI更新。然后通过sendMessage()等的方法通知UI
      更新,另外别忘了Handler写在主线程和子线程中的差别哦~
    2. 利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,更新UI时,把Runnable
      对象传进来就可以~

    2.AsyncTask全解析:


    1)为什么要用AsyncTask?

    答:我们能够用上述两种方法来完毕我们的异步操作,增加要我们写的异步操作比較多,或者较为繁琐,
    难道我们new Thread()然后用上述方法通知UI更新么?程序猿都是比較喜欢偷懒的,既然官方给我
    们提供了AsyncTask这个封装好的轻量级异步类。为什么不用呢?我们通过几十行的代码就能够完毕
    我们的异步操作,而且进度可控。相比起Handler,AsyncTask显得更加简单,快捷~当然,这仅仅适合
    简单的异步操作,另外。实际异步用的最多的地方就是网络操作。图片载入,传输数据等。AsyncTask
    临时能够满足刚開始学习的人的需求,谢谢小应用。可是到了公司真正做项目以后。我们很多其它的使用第三发的
    框架,比方Volley,OkHttp,android-async-http,XUtils等非常多,后面进阶教程我们会选1-2个框架进行
    学习,当然你能够自己找资料学习学习,可是掌握AsyncTask还是非常有必要的。


    2)AsyncTask的基本结构:

    AsyncTask是一个抽象类,一般我们都会定义一个类继承AsyncTask然后重写相关方法~
    官方API:AsyncTask

    • 构建AsyncTask子类的參数:

    • 相关方法与运行流程:

    • 注意事项:


    3.AsyncTask使用演示样例:

    由于我们还没学到Android网络那块,这里照应下各位刚開始学习的人。这里用延时
    线程来模拟文件下载的过程~后面讲到网络那里再给大家写几个样例~

    实现效果图:

    布局文件:activity.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        xmlns:tools="http://schemas.android.com/tools"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:orientation="vertical"  
        tools:context=".MyActivity">  
        <TextView  
            android:id="@+id/txttitle"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content" />  
        <!--设置一个进度条,而且设置为水平方向-->  
        <ProgressBar  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:id="@+id/pgbar"  
            style="?android:attr/progressBarStyleHorizontal"/>  
        <Button  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:id="@+id/btnupdate"  
            android:text="更新progressBar"/>  
    </LinearLayout>  

    定义一个延时操作。用于模拟下载:

    public class DelayOperator {  
        //延时操作,用来模拟下载  
        public void delay()  
        {  
            try {  
                Thread.sleep(1000);  
            }catch (InterruptedException e){  
                e.printStackTrace();;  
            }  
        }  
    }  

    自己定义AsyncTask

    public class MyAsyncTask extends AsyncTask<Integer,Integer,String>  
    {  
        private TextView txt;  
        private ProgressBar pgbar;  
    
        public MyAsyncTask(TextView txt,ProgressBar pgbar)  
        {  
            super();  
            this.txt = txt;  
            this.pgbar = pgbar;  
        }  
    
    
        //该方法不运行在UI线程中,主要用于异步操作,通过调用publishProgress()方法  
        //触发onProgressUpdate对UI进行操作  
        @Override  
        protected String doInBackground(Integer... params) {  
            DelayOperator dop = new DelayOperator();  
            int i = 0;  
            for (i = 10;i <= 100;i+=10)  
            {  
                dop.delay();  
                publishProgress(i);  
            }  
            return  i + params[0].intValue() + "";  
        }  
    
        //该方法运行在UI线程中,可对UI控件进行设置  
        @Override  
        protected void onPreExecute() {  
            txt.setText("開始运行异步线程~");  
        }  
    
    
        //在doBackground方法中,每次调用publishProgress方法都会触发该方法  
        //运行在UI线程中,可对UI控件进行操作  
    
    
        @Override  
        protected void onProgressUpdate(Integer... values) {  
            int value = values[0];  
            pgbar.setProgress(value);  
        }  
    }  

    MainActivity.java

    public class MyActivity extends ActionBarActivity {  
    
        private TextView txttitle;  
        private ProgressBar pgbar;  
        private Button btnupdate;  
    
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            txttitle = (TextView)findViewById(R.id.txttitle);  
            pgbar = (ProgressBar)findViewById(R.id.pgbar);  
            btnupdate = (Button)findViewById(R.id.btnupdate);  
            btnupdate.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    MyAsyncTask myTask = new MyAsyncTask(txttitle,pgbar);  
                    myTask.execute(1000);  
                }  
            });  
        }  
    }  

    本节小结:

    好的,本节一開始给大家普及了下应用程序。进程。线程,多线程,异步。同步的概念;接着又解说
    了下Android中为何要引入异步操作,然后介绍了下AsyncTask的使用方法,当然上面也说了。异步操作在网络
    操作用的较多,后面在解说网络操作时会用到这个AsyncTask,敬请期待~本节就到这里,谢谢~

  • 相关阅读:
    xxl-job docker版分布式任务
    nginx学习http_access_module模块
    nginx学习sub_filter模块
    nginx学习首页随机模块
    mysql使用命令
    laravel数据填充
    LINUX下统计代码行数
    检查字符串结尾 判断一个字符串(str)是否以指定的字符串(target)结尾。
    右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组。
    确保字符串的每个单词首字母都大写,其余部分小写。
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7221972.html
Copyright © 2011-2022 走看看