使用Handler出现的警告
零、原由
安卓中使用Hander时出现了如下警告:
This Handler class should be static or leaks might occur (anonymous android.os.Handler)
网上建议使用如下方案:
private Handler mHandler2 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});
但是又出现了如下警告:
'Handler(android.os.Handler.Callback)' is deprecated
都与内存泄漏有关,在API级别30中,Handler(Handler.Callback)构造函数被弃用。Android在这里解释了原因。
public Handler (Handler.Callback callback)
此构造函数已弃用。在处理程序构造期间隐式地选择一个循环器可能会导致错误,其中操作会自动丢失(如果处理程序不希望有新任务并退出)、崩溃(如果处理程序有时在thread上创建而没有活动循环器)或争用条件,threada处理程序所关联的地方并不是作者所预期的。相反,请使用执行器或显式指定循环器,使用LoopergetMainLooper、{linkandroid.view.View#getHandler}或类似的方法。如果为了兼容性需要隐式thread本地行为,请使用newHandler(Looper.myLooper(),callback)向读者说明。
壹、解决方案
使用Handler(Looper,Handler.Callback)构造函数并显式指定循环器。
案例1:如果您希望代码在main/UI thread上运行
Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic here
return true;
}
});
案例2:如果你想让代码在后台运行thread
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Using this handler to post tasks that running on a background thread.
Handler handler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic here
return true;
}
});
记住完成后释放thread。
handlerThread.quit(); // 或者是 handlerThread.quitSafely();
案例3:如果希望代码在后台thread上运行,并将结果返回main/UI thread。
// Using this handler to post tasks that run on main/UI thread
Handler uiHandler = new Handler(Looper.getMainLooper());
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Using this handler to post task that run on a background thread
Handler handler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic here
// Execute the code or pass the result back to main/UI thread
uiHandler.post(new Runnable() {
@Override
public void run() {
}
});
return true;
}
});
贰、效果
public class MainActivity extends AppCompatActivity {
private final Handler handler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
已经没有警告了。