android后台任务(一):Handler

一般网络请求,I/O操作这样费时的网络请求需要在工作线程进行而不是在UI主线程,不然会造成UI的卡顿。但是android不能在非UI线程更新UI,所以我们一般使用Looper+Handler+Thread来处理。
先看看一般的简洁使用。

package com.example.asus.practise;

public class MainActivity extends AppCompatActivity
{
    private TextView mTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.textView);

        Handler mHandler = new Handler();
        //延迟五秒处理这个处理这个消息,而不是让线程暂停5秒
        mHandler.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                mTextView.setText("11111");
            }
        },5000);
    }
}

但是上面这样容易造成内存泄漏,看下面的复杂实现:

package com.example.asus.practise;

public class MainActivity extends AppCompatActivity
{
    /**
     * 这里使用静态内部类继承Handler
     * 如果使用普通或者匿名内部类,Handler实例会持有父类MainActivity的引用
     * 而如果MainActivity被关闭之后Handler还没有被销毁
     * MainActivity就会因为被Handler持有引用而不会被回收,造成内存泄漏
     */
    private static class MyHandler extends Handler
    {
        //既然Handler不能持有MainActivity引用,但是又需要MainActivity对象,就需要一个弱引用
        private WeakReference<MainActivity> activityWeakReference;
        private TextView tv;

        public MyHandler(MainActivity activity)
        {
            activityWeakReference = new WeakReference<MainActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg)
        {
            MainActivity mainActivity = activityWeakReference.get();
            if (mainActivity == null)return;
            TextView tv = mainActivity.getmTextView();
            if (tv == null)return;
            switch (msg.what)
            {
                case 1:
                    tv.setText("1");
                    break;
                case 2:
                    tv.setText("2");
                    break;
            }
        }
    }
    private TextView mTextView;
    public TextView getmTextView()
    {
        return mTextView;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.textView);
        Handler mHandler = new MyHandler(this);
        Message msg = mHandler.obtainMessage(1);//最好不要自己新建Message
        mHandler.sendMessage(msg);
    }
}

这个看起来好像有点麻烦,主要是为了防止内存泄漏。
每次需要执行异步任务的时候,如果我们都需要写这么一套代码,显得很麻烦,于是就有了AsyncTask,它将这整个过程封装了,只留下几个方法让用户实现,用起来很方便,但是也容易造成内存泄漏,所以应该用更安全,更简单的方式来完成异步任务,Handler和AsyncTask都是不推荐的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值