上周参照网上代码,做了USB的初步探测程序,工作正常 。今天从硬件部拿到了一段例程,原本打算参考它来完善自己的程序。但运行之后总是报错,逐步跟进错误,进而发现了一个匪疑所思的问题。调试一天也未发现原因以及解决办法。在此做记录,留待以后解决或从网上得到帮助。

问题程序:

UsbHid.java:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

public class UsbHid extends Activity{
    private static UsbHid usbHid = null;
    Context context;
    private static final String TAG = "UsbHid";
    private UsbManager myUsbManager;
    private UsbDevice myUsbDevice;
    private boolean HasUsbDevice;
    ...

    private UsbHid(Context context) {
        this.context = context;
        myUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        HasUsbDevice = enumerateDevice();
        Log.d(TAG, "UsbHid init");
    }

    public bollean enumerateDevice() {
        if (myUsbManager == null)
            return -1;
        HashMap<String, UsbDevice> deviceList = myUsbManager.getDeviceList();
        if (!deviceList.isEmpty()) {
            ...
            return  true;
        }
        return false;
    }

    public static UsbHid getInstance(Context context) {
        if (usbHid == null) {
            usbHid = new UsbHid(context);
        }
        return usbHid;
    }
    public boolean getUsbDevice() {
        return HasUsbDevice;
    }
    ...
}
 

MainActivity.java:

public class MainActivity extends ActionBarActivity {
 UsbHid usbHid = null;

 UsbManager myUsbManager;
 UsbDevice myUsbDevice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

  usbHid = UsbHid.getInstance(this);

        if (usbHid.getUsbDevice()) {
            usbHid.ConnectUsbHid();
            this.setTitle("已连接USB设备");
        } else {
            this.setTitle("末检测到USB设备");
        }
        if (usbHid.getUsbDevice()) {
            UsbReadThread thread = new UsbReadThread();
            thread.start();
        }
  }
  ...
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

以上程序从原理上分析应该没有问题,但实际中deviceList.isEmpty()总是返回null。

更为奇怪的是,若将UsbHid.java中的

myUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HasUsbDevice = enumerateDevice();
移到MainActivity.java中,则没有问题,可以正常枚举设备。

前一天写的以上内容,今天原本打算暂时绕过以上问题,继续进行后续开发,毕竟这个问题不是不可避免的。但还是觉得应该再基于这个问题研究一下,因为这样才能够提高水平,丰富经验。

进行反复修改尝试,根据现象判断,最终发现了问题所在:

UsbHid.java:

public static UsbHid getInstance(Context context) {
        if (usbHid == null) {
            usbHid = new UsbHid(context);
        }
        return usbHid;
    }

就是这句导致的问题!将这句程序封掉后,可以枚举到设备,程序可以正常工作了。

具体原因尚不清楚,但初步分析应该是由于usbHid是静态变量(private static UsbHid usbHid = null;),放在全局存储区,因此回收的时候并没有马上释放掉。下次进程再启动时,它并不是null,而是上次一分配过的值。基于这个想法,做了实验,将上面这段代码改写如下:

public static UsbHid getInstance(Context context) {
        if (usbHid == null) {
            usbHid = new UsbHid(context);

return usbHid;
        }
        return null;
    }
改写程序的目的是测试是否每次都返回usbHid而非null。宏观上从程序运行现象来看应该是如果每次都返回usbHid,则每次程序都正常;如果有返回null的时候,则程序会停止运行。

测试结果印证了 猜测,一次成功接一次失败,即确实usbHid在前一次进程结束后并未彻底释放,而直到出错被停止运行后才被释放掉。

另外一个测试也验证了以上想法:将手机重启,之后运行以上程序,由于是第一此运行,因此完全正常,而后每次即使不插入usb设备,也不报错。这就说明了usbHid这个变量并没有被释放干净。

至于为何进程结束后,仍不能是放干净,则有待进一步深入,应该是与Java的回收机制有关了……

 

调试Android USB遇到的令人费解的问题的更多相关文章

  1. Eclipse中调试Android技巧

    Android eclipse中程序调试 一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的. 步骤如下. 1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键 ...

  2. 在 Chrome 中调试 Android 浏览器

    最近需要使用 Chrome Developer Tools 调试 Android 浏览器,但是官方指南并不是很好使,经过一番折腾,终于调试成功了,在此把经验分享给需要的朋友. Chrome Devel ...

  3. Web程序员开发App系列 - 调试Android和IOS手机代码(补图)

    Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...

  4. 在ubuntu下真机调试android程序出现设备没有访问权限

    今天把android的开发环境从windows平台切换到了ubuntu上. java jdk android-adt android-ndk都下好,环境变量都配好之后, 在调试程序的时候,出现设备没有 ...

  5. 理解WebKit和Chromium: 调试Android系统上的Chromium

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. Android上的调试技术 在Android系统上,开发人员能够使用两种不同的语言来开发应用程序,一种是Jav ...

  6. I.MX6 Android USB Touch eGTouchA.ini文件存放

    /******************************************************************** * I.MX6 Android USB Touch eGTo ...

  7. 通过Wifi调试Android应用

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  8. android usb Host模式下与usb Hid 设备的通信

    做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...

  9. 如何通过Chrome远程调试android设备上的Web网站

    网上的帖子很多,但很多都是老版本的,试过了,根本不管用,花了一天时间,终于在本机试验通过了,特记录下来,以备用.有需要的朋友也可以参考.先上一张图,看看PC端chrome上调试的效果: 左边是手机的模 ...

随机推荐

  1. MS SQLService中的*= 及 =*

    今天看到数据库中的存储过程中,有*= ,于是百度了一下,原来这个SQL2000以前的左连接,以后的版本中开启兼容也是可以用的. 于是拿出来在系统中的表中测试了一下果然如此 例: 有用户表D_user及 ...

  2. 简化版的Flappy Bird开发过程(不使用第三方框架)

    目录 .1构造世界 .2在世界中添加元素 .3碰撞检测 .4添加动画特效 .5总结 .0 开始之前 之前曾经用Html5/JavaScript/CSS实现过2048,用Cocos2d-html5/Ch ...

  3. 用python下载辞典

    用python下载词源词典Etymoline Online Etymology Dictionary是最好的 English 词源词典,现在来说没有之一.但是,一直在PC上查单词有时不是很方便,遂就想 ...

  4. 堆排序 C++

    1 堆排序拥有插入排序的优点 (是一种原地排序算法只需要存储常数个元素在输入数组以外 即省空间), 同时拥有合并排序算法的复杂度 nlgn,逼格有点高 2 堆数据结构 是一个数组对象,可以被视为一颗完 ...

  5. java.util.AbstractStringBuilder源码分析

    AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大 ...

  6. MySQL企业常用集群图解

      mysql集群架构图片 1.mysql企业常用集群架构 在中小型互联网的企业中.mysql的集群一般就是上图的架构.WEB节点读取数据库的时候读取dbproxy服务器.dbproxy服务器通过对S ...

  7. Javascript中的迭代、归并方法

    迭代方法 在Javascript中迭代方法个人觉得尤为重要,在很多时候都会有实际上的需求,javascript提供了5个迭代方法来供我们操作,它们分别为: every() 对数组中的每一个项运用给定的 ...

  8. 《jQuery、jQuery UI及jQuery Mobile技巧与示例》勘误收集

    此书由程学彬 (http://weibo.com/ironbin)和我合译完成,此篇博客作为勘误收集而用,若译文有误或者有任何疑问,欢迎留下评论,或者给我发邮件(地址:gzooler@gmail.co ...

  9. MongoDB入门三步曲1--安装、基本操作

    mongodb 基本操作 目录 mongodb安装 mongod启动 mongo shell启动 mongod 停止 mongodb基本操作:CRUD 数据插入 数据查询 数据更新 数据删除 集合删除 ...

  10. ssh自动登录的4种实现方法

    ssh自动登录的几种实现方法,记录在此.  1. 自动ssh/scp方法 A为本地主机(即用于控制其他主机的机器) ; B为远程主机(即被控制的机器Server), 假如ip为192.168.60.1 ...