最近在检查内存泄漏 发现之前使用得扫码工具一只存在泄漏问题 在页面关闭后content继续被引用存在 没找到好的解决办法 直接就换一个新得 在GitHub上翻了下 之前得依赖zbar 扫描速度明显比zxing快很多 所以就继续找个 使用zbar封装好的第三方 地址 https://github.com/bingoogolapple/BGAQRCode-Android
使用方式 上面写的很清楚 作者发布了2个版本得包 一个依赖zxing 一个是zbar 我还是用zbar得
优点是页面容易定制 修改起来很方便 方法也都封装好了 调用方便 不过介绍上说有的机型 会扫码失败 还有可能会有黑屏 我还没有遇到 记录一下我使用的情况吧
我用的应该是最新得版本了
compile 'cn.bingoogolapple:bga-qrcodecore:1.1.9@aar'//二维码扫描 compile 'cn.bingoogolapple:bga-zbar:1.1.9@aar'
上个代码
我做的是一个在viewpager中可以左右滑动的页面 所以是写在framgent里面得 因为是第二个子页面所以 会预加载将baseframgent 方法整理好
public abstract class BaseFramgent extends Fragment { public String fragmentTitle; /** * 是否可见状态 */ private boolean isVisible = false; /** * 页面是否加载 */ private boolean isPrepared = false; /** * 数据是否第一次加载 */ private boolean isFirstLoad = true; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = initViews(inflater, container, savedInstanceState); isPrepared = true; lazyLoad(); return view; } /** * 如果是与ViewPager一起使用,调用的是setUserVisibleHint * setUserVisibleHint 只有在Fragment切换的时候才被调用 * * @param isVisibleToUser 是否显示出来了 */ @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (getUserVisibleHint()) { isVisible = true; onVisible(); startThread(); } else { isVisible = false; onInvisible(); } } /** * 如果是通过FragmentTransaction的show和hide的方法来控制显示,调用的是onHiddenChanged. * 若是初始就show的Fragment 为了触发该事件 需要先hide再show * * @param hidden hidden True if the fragment is now hidden, false if it is not * visible. */ @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if (!hidden) { isVisible = true; onVisible(); startThread(); } else { isVisible = false; onInvisible(); } } /*再次调用可见方法*/ @Override public void onResume() { super.onResume(); if (getUserVisibleHint()) { if (isFirstLoad) { setUserVisibleHint(true); } else { startThread(); } } } /** * 可见时调用 */ protected void onVisible() { lazyLoad(); } /** * 不可见调用 */ protected void onInvisible() { if (!isPrepared || isVisible) { //if (!isAdded() || !isVisible || !isFirstLoad) { return; } else { invisible(); } } /** * 不可见时停止 */ protected abstract void invisible(); /** * 加载 */ protected void lazyLoad() { Log.d("lazyLoad", "" + isPrepared + "," + isVisible + isFirstLoad); if (!isPrepared || !isVisible || !isFirstLoad) { //数据 isFirstLoad 如果为true return; } else { //当页面可见 初始化完成 数据未加载过 isFirstLoad = false; initData(); } } protected abstract View initViews(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); /** * 布局加载得方法 */ protected abstract void initData(); /** * 需要控制得线程 * * @return */ protected abstract void startThread(); public String getTitle() { if (null == fragmentTitle) { setDefaultFragmentTitle(null); } return TextUtils.isEmpty(fragmentTitle) ? "" : fragmentTitle; } public void setTitle(String title) { fragmentTitle = title; } /** * 设置fragment的Title直接调用,若不显示该title 可以不做处理 * * @param title 一般用于显示在TabLayout的标题 */ protected abstract void setDefaultFragmentTitle(String title); }
方法做了修改 本来在initData中是加载布局得 不过 我直接加载了 就没有使用 添加startthread方法是需要 控制在可见后 需要开启得线程 比如说扫描得方法 要不然直接开启会导致 在不可见状态 就可以扫码成功 还有一些震动 动画得管理 便于在不可见时停掉 可见得方法写的很清楚了 有两种 根据加载得方式 来选择使用 不明白俩个方法区别得可以百度下 framgent扫描得方法
/** * Start camera. */ private void startScan() { mQRCodeView.startSpot(); }
/** * Stop camera. */ private void stopScan() { /** * 停止识别 */ if (null != mQRCodeView) { mQRCodeView.stopSpot(); } }
@Override public void onPause() { // Must be called here, otherwise the camera should not be released properly. stopScan(); super.onPause(); }
@Override public void onDestroy() { super.onDestroy(); stopScan(); mQRCodeView.stopCamera(); mQRCodeView.onDestroy(); }
开启摄像头得方法 直接放在初始化中就可以 以免当使用时初始化出现黑屏闪动 测试有的手机初始化会闪黑屏
mQRCodeView.startCamera();
private void init() { flight = (ImageView) view.findViewById(R.id.flight); mQRCodeView = (ZBarView) view.findViewById(R.id.zbarview); mQRCodeView.setDelegate(this); flight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { flashlight(flag); } }); }
/** * 灯光管理 * @param b */ private void flashlight(boolean b) { if (b) { //open mQRCodeView.openFlashlight(); flight.setBackgroundResource(R.mipmap.isflight); flag = false; } else { //close mQRCodeView.closeFlashlight(); flight.setBackgroundResource(R.mipmap.flight); flag = true; } }
/** * 加载布局 */ @Override protected void initData() { Log.d("initData", "initData"); } /** * 不可见 */ @Override protected void invisible() { Log.d("invisible", "invisible"); stopScan(); flashlight(false); } /** * 开启需要得线程 */ @Override protected void startThread() { Log.d("startThread", "startThread"); startScan(); }
功能都有了 扫描时间比之前得稍微慢了一点 不过也可以 内存泄漏检测 有10几k 不需要考虑了 基本符合要求