版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39582021/article/details/84110744
内存泄漏参考: https://blog.csdn.net/womengmengyan/article/details/52315564
以下代码具备的功能:
1. 取消当前添加的所有 AsyncTask , 尽量减少重复的网络请求任务
(场景: 我们需要在一个界面中定时每 10s 请求一次网络获取一次数据 ,我们知道网络请求时间是不固定的 ,可能很快的请求完成,也可能很慢,因此,我为了尽量节省开销,希望每次都能在指定的时间执行一次网络请求就好了) |
2. 尝试解决内存泄漏问题
(内存泄漏,多是由于有些界面或对象销毁或生命周期结束后,仍然有一些引用持有该界面或对象 ,如: 想在一个已经销毁的界面中进行更新UI操作, 内存泄漏带来的影响: 随着泄漏的累积,app将消耗完内存) |
3. 循环请求网络
实现定时请求网络的功能 |
代码开始 ---->>>
Activity 部分:
public class MainActivity extends AppCompatActivity{
private static final String TAG = "MainActivity";
private List<String> showData = new ArrayList<>();
private SoftHandler mHandler = new SoftHandler(this);
private ImRunnable mImRunnable;
private MainAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
mImRunnable = new ImRunnable();
mHandler.removeCallbacks(mImRunnable);//清除上一次任务的影响
mHandler.postDelayed(mImRunnable, 300);//延时请求网络
}
private void initView() {
RecyclerView rcv = (RecyclerView) findViewById(R.id.rcv);
rcv.setLayoutManager(new GridLayoutManager(this, 4));
mAdapter = new MainAdapter(showData);
rcv.setAdapter(mAdapter);
}
//执行延时任务
private class ImRunnable implements Runnable, OnResponseCallback {
@Override
public void run() {
Log.i("NotifyService", "run: " + Thread.currentThread());
if (NetUtils.isNeedLoading) {
HashMap<String, String> parameters = new HashMap<>();
parameters.put("key", "value");
NetUtils netUtils = new NetUtils(MainActivity.this,this);
NetUtils.putTaskFloor(netUtils);//todo 保存每次创建的 AsyncTask 对象(弱引
用),在取消全部的时候会用到
netUtils.execute(new TestWeb(parameters));
}
//重复执行本身
mHandler.postDelayed(this, 300);
}
@Override
public void onSuccess(List<String> stringList) {
Log.i(TAG, "onSuccess: ");
if (stringList.get(0).equals("pass")) {
stringList.remove(0);
showData.clear();
showData.addAll(stringList);
mAdapter.setData(showData);
mAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "更新了数据!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "数据读取失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFail() {
Log.i(TAG, "onFail: ");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
showData.clear();
showData = null;
NetUtils.isNeedLoading = false;
mHandler.removeCallbacksAndMessages(null);
System.gc();
}
}
public class SoftHandler extends Handler {
//使用软引用,方便系统回收
private final WeakReference<Activity> mActivity;
public SoftHandler(Activity activity) {
mActivity = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
AsyncTask 部分:
public class NetUtils extends AsyncTask<BaseRequest, Void, List<String>> {
public static List<WeakReference<NetUtils>> allTask = new ArrayList<>();//临时保存任务
private WeakReference<Activity> weakAty;
private final OnResponseCallback mOnResponseCallback;
public static boolean isNeedLoading = true;
public static boolean isNeedSingleTask = true;//是否需要每次只允许一个任务执行
public NetUtils(Activity activity, OnResponseCallback onResponseCallback) {
this.mOnResponseCallback = onResponseCallback;
weakAty = new WeakReference<Activity>(activity);
}
public static void putTaskFloor(NetUtils netUtils) {
allTask.add(new WeakReference<NetUtils>(netUtils));
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected List<String> doInBackground(BaseRequest... voids) {
isNeedLoading = false;
if (isCancelled()) {
return null;
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("NetUtils", "doInBackground:");
return null;
}
@Override
protected void onPostExecute(List<String> stringList) {
super.onPostExecute(stringList);
isNeedLoading = true;
if (isNeedSingleTask) {
cancelAllRunningTask();//todo 拿到结果后,将再等待中的任务全部取消
}
Activity mActivity;
Activity activity = mActivity = (Activity) weakAty.get();
if (activity != null && !activity.isFinishing()) {
//activity != null && !activity.isFinishing() 决定了是否继续让持有的 activity 做事
//即只有当当前的 activity 没有 finish 的时候我们才有必要去更新UI
if (stringList != null) {
if (stringList.get(0).equals("pass")) {
if (mOnResponseCallback != null) {
mOnResponseCallback.onSuccess(stringList);
}
} else {
if (mOnResponseCallback != null) {
mOnResponseCallback.onFail();
}
}
} else {
if (mOnResponseCallback != null) {
mOnResponseCallback.onFail();
}
}
}
Log.e("NetUtils", "onPostExecute: 正在执行 AsyncTask from NetUtils");
}
public static void cancelAllRunningTask() {
if (allTask != null && allTask.size() > 0) {
for (int i = 0; i < allTask.size(); i++) {
NetUtils netUtils = allTask.get(i).get();
if (!netUtils.isCancelled()) {
netUtils.cancel(true);//没有取消就取消
Log.w("NetUtils", "cancelAll: 正在执行 AsyncTask from NetUtils");
allTask.remove(i);
} else {
allTask.remove(i);
}
int size = NetUtils.allTask.size();
Log.i("NetUtils", "cancelAllRunningTask: 取消一个任务后还有多少: "+size);
}
}
}
}
public interface OnResponseCallback {
void onSuccess(List<String> stringList);
void onFail();
}
结束: 如果有更好的写法,请不吝赐教 [握手]