关于adb4robotium跨进程框架抛出InputStream cannot be null的异常的解决方案

本文解决在真机测试中使用Robotium框架时遇到的InputStreamcannotbenull异常问题。通过分析发现,该问题是由于adb命令在手机端运行时权限不足导致。文中提供了修改后的代码及jar包。

之前我写的关于利用adb框架来进行robotium跨进程操作的文章中,有些朋友使用真机进行测试时,遇到一个比较奇怪的问题,会抛出"InputStream cannot be null"的异常。经过检查发现是由于代码中要生成的uidump.xml文件并没有在目标文件夹中生成,导致后面在使用File对象处理时,直接抛异常了。

这个问题其实比较怪异,经分析问题原因是跟adb命令在robotium框架中使用时,由于robotium是运行在手机端的,它跟在PC上使用有着比较大的差异。在手机端运行adb命令必须严格遵循android系统对权限的规定。具体的分析可以见我的这篇文章:http://blog.youkuaiyun.com/qingchunjun/article/details/43343735。所以在真机环境下,由于环境的不同,原框架代码是不能直接使用的,需要相应的修改,主要是修改生成uidump.xml那个方法,以及input命令的发送方式(由于在android中不同进程要模拟按键操作需要injectEvent权限,所以必须要root之后才能使用)。具体的代码及修改后的jar可以从这里下载:http://download.youkuaiyun.com/detail/qingchunjun/8508239。


如果是遇到这个问题的朋友,可以使用这个新的jar包试试。如果有问题的话,欢迎在留言中给我提出来,谢谢。

private void sendFileChunks(Uri uri) throws IOException, InterruptedException { appendLog("Preparing to send file..."); InputStream ins = getContentResolver().openInputStream(uri); if (ins == null) { appendLog("Cannot open file input stream."); return; } // get size (best effort) long total = -1; Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null) { int idx = cursor.getColumnIndex(OpenableColumns.SIZE); if (idx >= 0 && cursor.moveToFirst()) { total = cursor.getLong(idx); } cursor.close(); } int payloadSize = negotiatedMtu - 3; byte[] buffer = new byte[payloadSize]; int read; long sent = 0; int packetIndex = 0; // 包序号 final boolean useWriteNoResp = (writeCharacteristic.getWriteType() == BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); // 动态延时(ms),MTU越大,可以略大延时避免丢包 //int baseDelay = Math.max(5, (int)(payloadSize / 4.0)); // 简单经验公式,可微调 long startTime = System.currentTimeMillis(); // 🔹开始计时 while ((read = ins.read(buffer)) > 0) { byte[] payload = Arrays.copyOf(buffer, read); packetIndex++; boolean sentOk = false; int retry = 0; int maxRetries = 15; long retryDelay = 6; // 初始重试延时 6ms // 自动重试机制 while (!sentOk && retry < maxRetries) { writeCharacteristic.setValue(payload); sentOk = bluetoothGatt.writeCharacteristic(writeCharacteristic); if (!sentOk) { retry++; Thread.sleep(retryDelay); // 可根据设备吞吐量动态调整 retryDelay *= 2; // 重试时间翻倍 } } if (!sentOk) { appendLog("⚠ writeCharacteristic returned false! Waiting 10ms..."); Thread.sleep(10); continue; // 再尝试下一个包 }else { appendLog("Packet #" + packetIndex + " | size=" + read + " bytes | write() returned " + sentOk); } sent += read; if (total > 0) { appendLog(String.format(Locale.US, "Progress: %d/%d bytes", sent, total)); } else { appendLog(String.format(Locale.US, "Progress: %d bytes sent", sent)); } if (!useWriteNoResp) { // 有响应写,等待回调 synchronized (writeLock) { writeLock.wait(); } } else { // 无响应写,动态延时,防止BLE栈溢出 //Thread.sleep(baseDelay); } } ins.close(); long endTime = System.currentTimeMillis(); // 🔹结束计时 long duration = endTime - startTime; appendLog(String.format(Locale.US, "✅ File send finished. Total: %d bytes, Packets: %d, Time: %.2f sec (%.2f KB/s)", sent, packetIndex, duration / 1000.0, (sent / 1024.0) / (duration / 1000.0))); } 请用中文回答。这个发送函数,有时能到几十K每s,有时又只有几K每秒,是失败重发的延时策略影响,请调整策略提高每次的发送速度
最新发布
11-08
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值