Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

android 使用asynctask结合fragment更新UI(另附线程池管理示例)

$
0
0

使用asynctask结合fragment更新UI。在android上有不少设计都是使用fragment,因为使用fragment的生命周期可以和activity一起管理,再受到横竖屏旋转也可以保持稳定。使用asynctask,大家都很熟悉,这个有一个更新进度方法啦。就是巧妙使用这个方法。然后还能耗时工作放在这里。我写的这个可以作为定时器使用。更新的时间可以自已设置。

demo下载:http://download.csdn.net/detail/qq_16064871/9824371

1,效果图




2,主要代码

    public class LoopAsynTaskUpdate extends AsyncTask<Long, Long, Boolean> {
        // 需要循环执行的次数
        private WeakReference<onAsynTaskUpdateListener> mOnListener;
        private long mStartMillTime = 0;

        public void setAsynTaskUpdateListener(onAsynTaskUpdateListener listener) {
            mOnListener = null;
            mOnListener = new WeakReference<>(listener);
        }

        @Override
        protected Boolean doInBackground(Long... arg0) {
            synchronized (CusomAsyncTaskFragment.class) {
                long nCurrentLoopIndex = 0;
                while (mAsynBackSmoothRunning) {
                    if (mStartMillTime == 0) mStartMillTime = SystemClock.elapsedRealtime();
                    long havePassTime = SystemClock.elapsedRealtime() - mStartMillTime;
                    if (havePassTime < nCurrentLoopIndex * arg0[0]) {
                        try {
                            Thread.sleep(nCurrentLoopIndex * arg0[0] - havePassTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    nCurrentLoopIndex++;
                    if (mOnListener.get() == null) continue;
                    // 通知界面当前进行的状态
                    publishProgress(nCurrentLoopIndex);
                }
                return true;
            }
        }

        @Override
        protected void onProgressUpdate(Long... values) {
            //更新进度条的回调,改成刷新界面
            if (mOnListener.get() != null) mOnListener.get().asynTaskUpdateCallBack(true);
        }

        @Override
        protected void onPostExecute(Boolean b) {
            //  通知UI, 并直接返回不再循环
            if (mOnListener.get() == null) return;
        }
    }


 extends AsyncTask<Long, Long, Boolean> 和 doInBackground(Long... arg0)以及onProgressUpdate(Long... values) 里面参数都是对应的。我这里使用Long类型,因为

传入是1000L(1秒)。就是毫秒啦,这样更加灵活。

WeakReference<onAsynTaskUpdateListener> mOnListener; 这个回调的监听,使用弱引用,可以保证线程或者对象安全。

synchronized 里面使用这个关键字,就是为了保持一个更新状态。

与Fragment结合的完整代码如下:

package com.asynctask.sample.task;

import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;

import java.lang.ref.WeakReference;
import java.util.concurrent.Executors;

/**
 * 依赖于Fragment的生命周期
 */
public class CusomAsyncTaskFragment extends Fragment {
    // 后台任务是否继续执行
    private boolean mAsynBackSmoothRunning = false;
    // 后台任务实例
    private LoopAsynTaskUpdate mLoopAsynTaskUpdate;

    public void runTask(onAsynTaskUpdateListener listener, Long millisecond) {

        // 任务继续运行, 但是已经申请结束
        if (mLoopAsynTaskUpdate != null && !mAsynBackSmoothRunning)
            mLoopAsynTaskUpdate = null;

        // 任务正在运行,不处理,直接退出
        if (mLoopAsynTaskUpdate != null && mAsynBackSmoothRunning) {
            mLoopAsynTaskUpdate.setAsynTaskUpdateListener(listener);
            return;
        }

        // 开启任务
        mLoopAsynTaskUpdate = new LoopAsynTaskUpdate();
        mLoopAsynTaskUpdate.setAsynTaskUpdateListener(listener);
        mAsynBackSmoothRunning = true;
        mLoopAsynTaskUpdate.executeOnExecutor(Executors.newFixedThreadPool(3), millisecond);
    }

    public void updateListener(onAsynTaskUpdateListener listener) {
        if (mLoopAsynTaskUpdate != null) mLoopAsynTaskUpdate.setAsynTaskUpdateListener(listener);
    }

    public void stopTask() {
        mAsynBackSmoothRunning = false;
        mLoopAsynTaskUpdate = null;
    }

    public boolean getTaskStatus() {
        return mAsynBackSmoothRunning;
    }

    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onDestroy() {
        stopTask();
        super.onDestroy();
    }

    //接口回调
    public interface onAsynTaskUpdateListener {
        public abstract void asynTaskUpdateCallBack(Boolean update);
    }

    public class LoopAsynTaskUpdate extends AsyncTask<Long, Long, Boolean> {
        // 需要循环执行的次数
        private WeakReference<onAsynTaskUpdateListener> mOnListener;
        private long mStartMillTime = 0;

        public void setAsynTaskUpdateListener(onAsynTaskUpdateListener listener) {
            mOnListener = null;
            mOnListener = new WeakReference<>(listener);
        }

        @Override
        protected Boolean doInBackground(Long... arg0) {
            synchronized (CusomAsyncTaskFragment.class) {
                long nCurrentLoopIndex = 0;
                while (mAsynBackSmoothRunning) {
                    if (mStartMillTime == 0) mStartMillTime = SystemClock.elapsedRealtime();
                    long havePassTime = SystemClock.elapsedRealtime() - mStartMillTime;
                    if (havePassTime < nCurrentLoopIndex * arg0[0]) {
                        try {
                            Thread.sleep(nCurrentLoopIndex * arg0[0] - havePassTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    nCurrentLoopIndex++;
                    if (mOnListener.get() == null) continue;
                    // 通知界面当前进行的状态
                    publishProgress(nCurrentLoopIndex);
                }
                return true;
            }
        }

        @Override
        protected void onProgressUpdate(Long... values) {
            //更新进度条的回调,改成刷新界面
            if (mOnListener.get() != null) mOnListener.get().asynTaskUpdateCallBack(true);
        }

        @Override
        protected void onPostExecute(Boolean b) {
            //  通知UI, 并直接返回不再循环
            if (mOnListener.get() == null) return;
        }
    }
}

用Fragment生命周期来管理AsyncTask。确实是个不错选择。

rxpermissions是针对6.0以上权限管理的库,思想就是基于Fragment来设计的。因为Fragment不用界面也是可以的。就可以做很多事情。

github网址:https://github.com/tbruyelle/RxPermissions

3,activity调用

package com.asynctask.sample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import com.asynctask.sample.task.CusomAsyncTaskFragment;

public class AsynTaskUpdateUIActivity extends AppCompatActivity implements View.OnClickListener
        ,CusomAsyncTaskFragment.onAsynTaskUpdateListener {
    private CusomAsyncTaskFragment mCusomAsyncTaskFragment = null;
    private TextView mTvShow;
    private int nIndex = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_asyntask_update);
        initView();
    }

    private void initView() {
        findViewById(R.id.button).setOnClickListener(this);
        findViewById(R.id.button1).setOnClickListener(this);
        mTvShow = (TextView)findViewById(R.id.textView);

        mCusomAsyncTaskFragment = (CusomAsyncTaskFragment)(getFragmentManager()).findFragmentByTag("AsyncTaskFragment");
        if (mCusomAsyncTaskFragment == null) {
            mCusomAsyncTaskFragment = new CusomAsyncTaskFragment();
            getFragmentManager().beginTransaction().add(mCusomAsyncTaskFragment, "AsyncTaskFragment").commit();
        }
        if (mCusomAsyncTaskFragment.getTaskStatus())
            mCusomAsyncTaskFragment.updateListener(this);
    }

    @Override
    public void asynTaskUpdateCallBack(Boolean update) {
        nIndex ++;
        if(mTvShow != null)
            mTvShow.setText("" +  nIndex);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                mCusomAsyncTaskFragment.runTask(this,50L);
                break;
            case R.id.button1:
//                startActivity(new Intent(this,DirectGridActivity.class));
                break;
        }
    }
}

4,网上找到一个线程池管理类

也可以借鉴一下,用在什么需求上也是可以的。

package com.asynctask.sample.task;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 下载线程池管理
 */
public class ThreadPoolManager {
    /**
     * 单例设计模式(饿汉式)
     *  单例首先私有化构造方法,然后饿汉式一开始就开始创建,并提供get方法
     */
    private static ThreadPoolManager mInstance = new ThreadPoolManager();
    public static ThreadPoolManager getInstance() {
        return mInstance;
    }

    private int corePoolSize;//核心线程池的数量,同时能够执行的线程数量
    private int maximumPoolSize;//最大线程池数量,表示当缓冲队列满的时候能继续容纳的等待任务的数量
    private long keepAliveTime = 1;//存活时间
    private TimeUnit unit = TimeUnit.HOURS;
    private ThreadPoolExecutor executor;
    private ThreadPoolManager() {
        /**
         * 给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)
         */
        corePoolSize = Runtime.getRuntime().availableProcessors()*2+1;
        maximumPoolSize = corePoolSize; //虽然maximumPoolSize用不到,但是需要赋值,否则报错
        executor = new ThreadPoolExecutor(
                corePoolSize, //当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务
                maximumPoolSize, //5,先corePoolSize,然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
                keepAliveTime, //表示的是maximumPoolSize当中等待任务的存活时间
                unit,
                new LinkedBlockingQueue<Runnable>(), //缓冲队列,用于存放等待任务,Linked的先进先出
                Executors.defaultThreadFactory(), //创建线程的工厂
                new ThreadPoolExecutor.AbortPolicy() //用来对超出maximumPoolSize的任务的处理策略
        );
    }
    /**
     * 执行任务
     */
    public void execute(Runnable runnable){
        if(runnable==null)return;

        executor.execute(runnable);
    }
    /**
     * 从线程池中移除任务
     */
    public void remove(Runnable runnable){
        if(runnable==null)return;

        executor.remove(runnable);
    }
}

简单测试调用

package com.asynctask.sample;

import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.asynctask.sample.task.ThreadPoolManager;

public class ThreadPoolTestActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView mTvShow;
    private int nIndex = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_asyntask_update);
        initView();
        /**
         * 创建九个任务
         */
        for (int i = 0; i < 9; i++) {
            ThreadPoolManager.getInstance().execute(new DownloadTask(i));
        }
    }
    /**
     * 模仿下载任务,实现Runnable
     */
    class DownloadTask implements Runnable{
        private int num;
        public DownloadTask(int num) {
            super();
            this.num = num;
            Log.e("JAVA", "task - "+num + " 等待中...");
        }
        @Override
        public void run() {
            Log.e("JAVA", "task - "+num + " 开始执行了...开始执行了...");
            SystemClock.sleep(5000); //模拟延时执行的时间
            Log.e("JAVA", "task - "+num + " 结束了...");
        }
    }

    private void initView() {
        findViewById(R.id.button).setOnClickListener(this);
        findViewById(R.id.button1).setOnClickListener(this);
        mTvShow = (TextView)findViewById(R.id.textView);
        mTvShow.setText("看log打印,界面没什么用");
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                break;
            case R.id.button1:
                break;
        }
    }
}

这个线程池代码也有一并打包:

demo下载:http://download.csdn.net/detail/qq_16064871/9824371

作者:qq_16064871 发表于2017/4/25 22:36:06 原文链接
阅读:154 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>