老刘安卓之使用异步写倒计时

来源:互联网 发布:淘宝韩都衣舍旗舰店 编辑:程序博客网 时间:2024/04/29 06:26

相信大家学习了异步Async,也使用之进行了网络下载,这里使用async进行倒计时操作:

(一)复习一下Async:

异步任务:
什么是异步任务?一切使用多线程来完成的任务均可以称为异步任务----------->使用线程来完成的任务
使用异步任务有啥好处呢:提高CPU的利用率
使用异步任务坏处在哪里呢?
1>:加重了CPU的负担
2>:容易出现线程安全问题
3>:容易造成死锁

使用异步任务的必要性
Android中单线程模型
Anroid到底是如何来运行程序的?
当Android的虚拟机在调用咋们的Activiyt对象来完成现实压栈的时候
将当前的对象运行在了一个叫做MainThread的主线程中,这个线程又叫做UI线程
UI线程这个名字是如何得来的呢?是因为这个主线程我那个只有一个特定的工作那就是刷新UI 这个线程的主要工作就是管理UI
Android的单线程模型指的是什么?
指的就是上面我们提到的这个UI线程
那么这个模型具体指的是什么呢?
1>:在Android的单线程模型中第一点:刷新UI只能在主线程来完成
2>:耗时操作必须在异步中完成有哪些是耗时的 操作? 网络我访问 IO流的使用 数据库的访问 咋们以后遇到这个问题的时候需要使用线程来完成

所以:
需要的做多的使用异步来完成的是:
网络访问:软件------>服务器数据的获取,开发的话那么访问网和数据库都要放到一异步任务重去完成
数据库的访问:
2.3以前的版本 山寨市场上不规整 有些手机 三星必须要求访问数据库必须放子线程 中兴 华为 联想 只要是数据库的访问都放到线程中
(二)异步任务的用法
AsyncTask是什么?是一个线程池
对于Android系统而言4.4以前的版本
允许一次性最多运行5个线程
内部定义了最多在线程池中存在的线程数是128
对于4.4以后的版本
1>:那个线程最最多运行的线程数也是根据当前CPU的性能来动态决定的2-4个线程,所以一般就拿来做些比较小的异步操作
private static final intCORE_POOL_SIZE= Math.max(2, Math.min(CPU_COUNT- 1,4));
2>:当前线程池中的最大的线程数也是动态决定的
注意:在4.4的版本以后那个线程池的默认的是同一时间段只能执行一个任务
但是我们也可以自定义线程池,这个后边说到。
 (三)异步任务的取消(后边会用到)
myAsyncTask.cancel(true)  这个方法和线程中的interrupt方法是一样的能够终止正处于阻塞状态的线程。
很多开发者会认为一个在Activity中创建的AsyncTask会随着Activity的销毁而销毁。然而事实并非如此。AsyncTask会一直执行, 直到doInBackground()方法执行完毕。然后,如果 cancel(boolean)被调用, cancel(true)调用的是onCancelled(Result result) 方法那么onCancelled(Result result) 方法会被执行;否则,执onPostExecute(Result result) 方法。如果我们的Activity销毁之前,没有取消 AsyncTask,这有可能让我们的AsyncTask崩溃(crash)。因为它想要处理的view已经不存在了。所以,我们总是必须确保在销毁活动之前取消任务。总之,我们使用AsyncTask需要确保AsyncTask正确地取消。
       另外,即使我们正确地调用了cancle() 也未必能真正地取消任务。因为如果在doInBackgroud里有一个不可中断的操作,比如BitmapFactory.decodeStream(),那么这个操作会继续下去。就是在图片的操作一旦进行是取消不了的!!
好的,上代码:
public class GuideActivity extends AppCompatActivity {    @Bind(R.id.skip_text)    TextView skipText;    @Bind(R.id.skip_seconds)    TextView skipSeconds;    private TimeCount time;    private int count = 10;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_guide);        ButterKnife.bind(this);
//异步类count:        final Count myCount = new Count(this);        myCount.execute(count);        skipText.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(GuideActivity.this, HomePageActivity.class);                startActivity(intent);                finish();
//如果中途点击跳过浏览,那么就调用取消这个方法                myCount.cancel(true);            }        });
好的,下面是count代码:
package com.example.administrator.newsinfor.utils;import android.content.Context;import android.content.Intent;import android.graphics.Color;import android.os.AsyncTask;import android.widget.TextView;import android.widget.Toast;import com.example.administrator.newsinfor.Activity.GuideActivity;import com.example.administrator.newsinfor.Activity.HomePageActivity;import com.example.administrator.newsinfor.R;/** * Created by Administrator on 2016/10/20 0020. */public class Count extends AsyncTask<Integer, Integer, Integer> {// 参数Context context;第一个参数含义接受传过来的前面execute的参数就是doinbackgroud返回参数。// 参数2:进度更新upgrade,参数3:返回值doin的返回类型post的传入参数//你写这边的构造函数参数,需要自己这边有定义才行    private GuideActivity guideActivity;//这个有实际意义,不是空的对象需要赋值    private int num;    private TextView skip_seconds;    public Count(Context context) {        if (context instanceof GuideActivity) {            guideActivity = (GuideActivity) context;        }    }    @Override    protected void onPreExecute() {        super.onPreExecute();        skip_seconds = (TextView) guideActivity.findViewById(R.id.skip_seconds);    }    @Override    protected Integer doInBackground(Integer... params) {        int count = params[0];        while (count > 0) {            publishProgress(count);            count--;            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }        return null;    }    @Override    protected void onProgressUpdate(Integer... values) {        super.onProgressUpdate(values);        skip_seconds.setClickable(false);        skip_seconds.setText(values[0] + "秒");        skip_seconds.setTextColor(Color.RED);    }    @Override    protected void onPostExecute(Integer integer) {        super.onPostExecute(integer);        //运行到这里表示运行完了,来个事后提示,我调用了oncacell来取消这步操作        Toast.makeText(guideActivity, "进入主页面", Toast.LENGTH_SHORT).show();        Intent intent = new Intent(guideActivity, HomePageActivity.class);        guideActivity.startActivity(intent);        guideActivity.finish();    }}
当然也可以使用安卓自带的类来实现:
/* 定义一个倒计时的内部类 */class TimeCount extends CountDownTimer {    public TimeCount(long millisInFuture, long countDownInterval) {        super(millisInFuture, countDownInterval);//参数依次为总时长,和计时的时间间隔    }    @Override    public void onFinish() {//计时完毕时触发        Intent intent = new Intent(GuideActivity.this, HomePageActivity.class);        startActivity(intent);        finish();    }    @Override    public void onTick(long millisUntilFinished) {//计时过程显示        skipSeconds.setClickable(false);        skipSeconds.setText(millisUntilFinished / 1000 + "秒");        skipSeconds.setTextColor(Color.RED);    }}
ok,that is all~

0 0
原创粉丝点击