哪一种更好的方式来使用处理程序。任何优点。我遇到的所有例子似乎都给出了内联版本。使用处理程序Android
在类中使用执行器Handler.Callback
并实现接口方法。
或
使用内嵌代码版本
private Handler mHandler = new Handler(){ ....};
哪一种更好的方式来使用处理程序。任何优点。我遇到的所有例子似乎都给出了内联版本。使用处理程序Android
在类中使用执行器Handler.Callback
并实现接口方法。
或
使用内嵌代码版本
private Handler mHandler = new Handler(){ ....};
常见的术语或这些内嵌类定义为匿名类。
你可以阅读更多关于这些的讨论Java/Android: anonymous local classes vs named classes
本质上的主要区别是readbility,编码的速度,再利用和范围。
从资源的角度来看,匿名类的创建可能会导致垃圾回收器的开销,如Avoid Creating Unnecessary Objects中所讨论的。我不确定匿名类创建的确切细节,但是,在类上实现接口更高效是合乎逻辑的。
@WilliamTMallard提供了一个不是要做的例子。在他的例子中,应该在类上实现一个长而复杂的句法复杂的处理程序,而不是匿名处理程序,因为在内联定义时难以阅读和编辑。
这个真没有回答上述问题,因为我不知道什么是“最好的办法”是,它可能取决于你在做什么。但是,我会解释我在做什么以及为什么。
我正在写一个作为遥控器的应用程序。有几种活动会与受控设备进行交互,并根据命令的结果和活动的结果发生不同的事情。我不喜欢关于处理程序的两件事:A)他们最终成为一种“厨房水槽”构造,实现来自不同来源的功能,并且B)他们分离了一个动作(在我的情况下是发送命令)从处理该行为的结果。然而,使用一个匿名(正确的术语?我是一个noob。)处理程序作为参数允许我将逻辑保持在一起。下面是我的方法的伪代码:
command = "Wake up!";
mDeviceInterface.write(command, new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case DeviceInterface.MESSAGE_TIMEOUT: // Process the timeout.
announce("Device not responding.");
break;
case DeviceInterface.MESSAGE_READ: // Process the response.
byte[] readBuf = (byte[]) msg.obj;
if (readBuf[0] == 0x05) {
// Success, update device status.
} else {
announce("Error!");
break;
}
}
}
});
(一定要记住,这可能是值得你付出什么吧;))
http://developer.android.com/reference/android/os/Handler.html
package : android.os
public class
Handler
extends Object
一个处理程序,您可以发送和处理信息,并与一个线程的MessageQueue关联Runnable对象。每个Handler实例都与单个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它将绑定到正在创建它的线程的线程/消息队列 - 此后,它将消息和可运行消息传递到该消息队列,并在消息出来时执行它们队列。
有一个处理程序两种主要用途:作为在将来的某一时刻 要执行
〔实施例1所
使用处理器在应用初始页面。
if (!isFirstIn) {
mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS);
} else {
mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS);
}
/**************************************************************************************
*1. Handler
*/
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if(isAuto){
switch (msg.what) {
case GO_HOME:
goHome();
break;
case GO_GUIDE:
goGuide();
break;
}
}
super.handleMessage(msg);
}
};
private void goHome() {
Intent intent = new Intent(SplashActivity.this, MainAct.class);
SplashActivity.this.startActivity(intent);
SplashActivity.this.finish();
}
private void goGuide() {
Intent intent = new Intent(SplashActivity.this, GuideActivity.class);
SplashActivity.this.startActivity(intent);
SplashActivity.this.finish();
}
实施例2
在子线程使用处理程序请求网络,如果请求的工作可能需要时间。
new Thread(new Runnable(){
@Override
public void run() {
String versionPath = Parameters.getCheckVersionPath();
String result = RequestHelper.doGet(versionPath, null);
Message msg = new Message();
Bundle data = new Bundle();
data.putString("result",result);
msg.setData(data);
handler1.sendMessage(msg);
}
}).start();
handler1 = new Handler(){
@Override
public void handleMessage(Message msg) {
String result = msg.getData().getString("result");
JSONObject obj;
try {
obj = new JSONObject(result);
Map<String, String> versionInfo = Helper.getSoftwareVersion(obj);
if (versionInfo != null) {
newVersion = versionInfo.get("version");
updateUrl = versionInfo.get("url");
}
} catch (JSONException e) {
Log.w("net work error!", e);
}
}
};
实施例3
使用处理程序和定时器更新进度条。
logobar = (ImageView) findViewById(R.id.splash_bar);//progress bar.
logobarClipe = (ClipDrawable) logobar.getBackground();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
updateLogoBarHandler.sendEmptyMessage(0);
}}, 0, rate);
/**************************************************************************************
*2. Handler
*/
//update progress bar.
private Handler updateLogoBarHandler = new Handler() {
public void handleMessage(Message msg) {
if(logobarClipe.getLevel() < 10000){
//1.update image.
logobarClipe.setLevel(logobarClipe.getLevel() + rate*2);
//2.update text.
float percent = logobarClipe.getLevel() /100;
String percentTxtVerbose = String.valueOf(percent);
String percentTxt = percentTxtVerbose.substring(0, percentTxtVerbose.indexOf('.')) + "%";
bartxt.setText(percentTxt);
}else{
timer.cancel();
}
super.handleMessage(msg);
}
};
在Android中使用匿名类存在危险。如在this blog post描述 -
在Java中,非静态内部和匿名类保持一个隐含 参考它们的外部类。
这里有一个泄漏的机会。
所以,简短的答案是:实现接口方法或使用静态内部类(不包含外部类引用)。
例如,泄漏的安全处理程序可能看起来像这样:
private static class ChangeTextHandler extends Handler {
private final WeakReference activity;
public ChangeTextHandler(MainActivity activity) {
this.activity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = this.activity.get();
if (activity == null) {
Log.e(TAG, "Activity is null ChangeTextHandler.handleMessage()!");
return;
}
final String text = (String) msg.getData().get(BUNDLE_KEY);
if (!TextUtils.isEmpty(text)) {
switch (msg.what) {
// do something
}
}
}
}
我做了一个blog post around usage of Handlers,所以可能需要检查以及:)