使用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; } }
传入是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 查看评论