Android 与 Java最大的不同在于Handler机制, 通常比较耗时的操作例如网络IO或各种复杂的计算等都是新开子线程中进行的, 若放在主线程中,若超时会导致ANR错误, 但是子线程又不允许更新UI内容, 为了解决这个矛盾Android 巧妙的设计了Handler机制, 因为以前接触的部分项目均为与条码相关的项目,有些Android设备在进行条码扫描时,扫描的驱动会通过Handler机制发送Message对象来实现,因为在Activity中频繁的用到Handler,所以为了提高代码的复用性,想针对条码设备的Handler机制进行封装以提高开发的效率, 在网上搜索过此类问题的解决方案没有找到太多有价值的信息,经过自己对Handler的理解提出以下解决办法,若有不妥之处,或更好的解决方案希望大家能指正留言,不吝赐教,谢谢
package com.fzhang.util;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.Vibrator;
import com.mobilead.decodemanager.DecodeManager;
import com.mobilead.decodemanager.barcode.DecodeResult;
import java.io.IOException;
/**
* Created by fzhang on 2016/12/9.
*/
public class M80Util {
public Context context;
private Handler mHandler;
private Runnable runnable;
private String barcode;
private DecodeManager decodeManager;
private static final long[] VIBRATE_FAILED = {100, 400, 100, 400};
private static final long[] VIBRATE_SUCESS = {100, 400};
private Vibrator vibrator = null;
public M80Util(final Context context, final Runnable runnable) {
this.context = context;
//将handler对象与对应context的主Looper进行绑定
new Thread(new Runnable() {
@Override public void run() {
mHandler = new Handler(context.getMainLooper()){
@Override public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DecodeManager.MESSAGE_DECODER_COMPLETE:
DecodeResult result = (DecodeResult) msg.obj;
barcode = result.barcodeData;
runnable.run();
break;
case DecodeManager.MESSAGE_DECODER_FAIL:
break;
}
}
};
decodeManager = new DecodeManager(context,mHandler);
SoundManager.getInstance();
SoundManager.initSounds(context);
SoundManager.loadSounds();
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
}
}).start();
}
public Handler getmHandler() {
return mHandler;
}
public void setmHandler(Handler mHandler) {
this.mHandler = mHandler;
}
public void decode() {
try {
this.decodeManager.doDecode(3000);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public String getBarcode() {
return barcode;
}
public void close() {
try {
decodeManager.release();
SoundManager.cleanup();
decodeManager = null;
} catch (IOException e) {
e.printStackTrace();
}
}
public void good() {
SoundManager.playSound(1, 1);
vibrator.vibrate(VIBRATE_SUCESS, -1);
}
public void nogood() {
SoundManager.playSound(2, 1);
vibrator.vibrate(VIBRATE_FAILED, -1);
}
}
调用的代码如下:
package com.jyjs.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.fzhang.util.M80Util;
import com.jyjs.R;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
long sta = 0, end = 0;
Handler handler;//未封装以前需要编写初始化每个Activity的Handler的大量代码
M80Util m80Util;//扫描解码工具类
@BindView(R.id.button2) Button btn_start;
@BindView(R.id.button3) Button btn_end;
@BindView(R.id.tv_1) public TextView tv_1;
Runnable runnable = new Runnable() {
@Override public void run() {
tv_1.setText("fuck Android!!!");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
m80Util = new M80Util(MainActivity.this,new Runnable(){
@Override public void run() {
tv_1.setText(m80Util.getBarcode());
}
});
handler = m80Util.getmHandler();
}
@Override protected void onPause() {
super.onPause();
m80Util.close();
}
@OnClick(R.id.button2)
public void btn_start() {
m80Util.decode();//解码
m80Util.good(); //解码正确产生提示音和一次震动
}
@OnClick(R.id.button3)
public void btn_end() {
Toast.makeText(MainActivity.this, "Clear", Toast.LENGTH_SHORT).show();
tv_1.setText("");
m80Util.nogood(); //产生不正确提示音和两次震动
}
}
另外若其他子线程中需要修改UI内容的直接可通过handler.post(runnable)方式直接实现
如此完成了对Handler机制的简单封装