一般网络请求,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都是不推荐的。