工作中遇到的小问题的记录

这篇博客记录了作者在工作中遇到的一些小问题及其解决方案,包括Android文件拷贝时遇到的'open failed: EEXIST (file exists)'异常,原因是通过电脑资源管理器删除SD卡文件并未真正删除;Java字符串比较时误用'=='导致的ListView滚动卡顿问题,应该使用'equals()'方法;以及Android源码编译中遇到的GitError、XML模块缺失和编译速度慢的问题,分别给出了相应的解决办法。

工作中遇到的小问题的记录

①Android:open failed: EEXIST  (file exists)

现象:

⑴在实现一个SD卡中的文件从一个路径拷贝到另一个路径的功能时,需要测试当SD卡空间不够的情况下的情况。所以我先让空间保证足够,进行了一次拷贝操作,OK,程序正常。

⑵然后我把手机连接电脑,通过电脑的资源管理器删除了拷贝的文件,并且让空间不够拷贝。再次进行拷贝操作,这次程序会抛Exception open failed: EEXIST  (file exists)。

⑶然后我再次让空间足够拷贝,但是这次程序还是抛出Exception open failed: EEXIST  (file exists)。

解决:

当时遇到这个问题,我通过电脑的资源管理器查看,SD卡目录下并没有抛出异常的这个文件。通过adb shell命令去查看,目录下也不存在这个文件。

这让我非常的蒙,这是个啥情况,明明SD卡的目录下没有该文件,为啥会说文件存在,因为我通过判断file.exists()方法判断,这个方法也给我false的返回。

查看异常堆栈,发现因为是new FileOutPutStream(new File)这句代码抛出的异常,又查是不是字节流没有close什么的。

总之各种改代码,发现还是抛这个异常。搞得我以为是代码出问题,但是换了一个新的SD卡的路径进行拷贝,程序又OK了。当时真是疯了。

晚上回去洗澡的时候,灵光一闪,我记得以前把手机刷机bin拷贝到SD卡中刷机的时候,明明已经通过电脑资源管理器删除了SD卡中旧的刷机bin,但是拷贝的时候还是会空间不足。查看大小,空间的确没有释放。

通过adb shell 查看的话,又不存在被删除的bin,搞得每次都要重新格式化SD卡。

后来我就通过adb shell命令删除SD卡中的旧的刷机bin,这次就正常了,新的刷机bin成功拷贝。

想到这里,我就觉得是不是这次的程序也是因为我是通过电脑的资源管理器删除拷贝的文件导致的问题。

第二天,我修改代码,当拷贝失败的时候,通过代码(file.delete())去主动删除备份文件。再次测试先空间不够备份,再空间足够备份。成功,这次终于没有问题了。

总结:

Android 手机从某一个版本开始,是哪个版本我不知道了,但是我知道android 10,11是存在通过电脑资源管理器删除SD卡中的文件,有时候并没有真真正正删除的这个问题。

这个问题的现象是对于frameworks层来说,这个文件是不存在的,因为file.exists()方法返回的是false。但是对于底层来说,这个文件是存在的。所以程序抛出file exists的异常。

为啥这样觉得是因为抛出异常的代码如下:

package java.io;
    public FileOutputStream(File file, boolean append)
        throws FileNotFoundException
    {
        ......
        this.fd = IoBridge.open(name, flags);
                              ↓
package libcore.io;
    @libcore.api.CorePlatformApi
    public static FileDescriptor open(String path, int flags) throws FileNotFoundException {
        FileDescriptor fd = null;
        try {
            fd = Libcore.os.open(path, flags, 0666);
            // Posix open(2) fails with EISDIR only if you ask for write permission.
            // Java disallows reading directories too.
            if (S_ISDIR(Libcore.os.fstat(fd).st_mode)) {
                throw new ErrnoException("open", EISDIR);
            }
            return fd;
        } catch (ErrnoException errnoException) {
            try {
                if (fd != null) {
                    closeAndSignalBlockedThreads(fd);
                }
            } catch (IOException ignored) {
            }
            FileNotFoundException ex = new FileNotFoundException(path + ": " + errnoException.getMessage());
            ex.initCause(errnoException);
            throw ex;
        }
    }

如果你也遇到差不多的问题,也请想想自己是不是也是通过电脑的资源管理器删除文件导致的。

 

②Java 字符串的 == 和 equals()

现象:

最近在调查一个ListView滚动卡顿的bug,调查的最终结果就是程序会判断两个字符串是否相等,如果不等的话,就是重新刷新ListView的这项Item。

但是实际上这个时候两个字符串是相等的,并不需要刷新Item。

查看代码,发现前人写的代码如下:

if (String str1 != String str2) {
    刷新view
}

我去,我接受到的指导都是字符串是否相等是通过equals()进行判断,这边怎么用!=号的。为了防止自己找错代码了,还特意添加log,打出了str1和str2。值明明就是一样的。

果断把这个代码换成equals()方法判断,OK,滚动不卡顿了。

测试:

总结:

根据上图的代码和下面的Log,在判断字符串是否相等的时候,果断使用equals方法。

 

出现error.GitError: manifests rev-list这样的错误

repo sync出错log如下: 
Traceback (most recent call last): 
......
error.GitError: manifests rev-list (‘^HEAD’, u’32e0fb4acc12235c71938356550c9552252a2f16’, ‘–’): fatal: bad object 32e0fb4acc12235c71938356550c95552a2f16 
解法办法:

root@ubuntu:/home/xxx$ cd .repo/manifests
root@ubuntu:/home/xxx/.repo/manifests$ ls
default.xml  star.xml
root@ubuntu:/home/xxx/.repo/manifests$ git fetch
......
root@ubuntu:/home/xxx/.repo/manifests$ git diff
root@ubuntu:/home/xxx/.repo/manifests$ cd ../..
root@ubuntu:/home/xxx$ repo sync

从高通下载的Android源码编译报错

错误提示:

you may need to install the XML::Simple module

处理方法:

sudo apt-get install libxml-simple-perl

Android 11 源码mm编译慢

从比较早的版本,Android就换用ninja进行源码的编译。

然后在以前,如果我们只编译某一个模块的话,可以通过mm命令进行编译。但是mm在Android11上的编译非常慢。此时就可以通过ninja进行编译,提交速度了。

ninja -f out/combined-luncher的名称.ninja target -j4
 ①               ②                            ③

①ninja:ninja 可以不用安装 ,源码中 prebuild 中有此工具: 目录在prebuilts/build-tools/linux-x86/bin

②out/combined-<luncher名称>.ninja:这个文件在out目录下存在,在源码用make命令已经编译过一次的前提下,会生成这个文件。launcher的名称指的是源码编译你输入的product,即choosecombo 1 product 2命令的product

③target:模块的名字

 

Android TextView获取宽度

在最近写代码的时候,UI设计组只给了一个图,图上只规定了TextView中的字体大小,没有写TextView的大小,所以需要根据TextSize来获取TextView的Width。方法如下:

TextPaint paint = mTextView.getPaint();
float length = paint.measureText(mTextView.getText().toString())

 

升级Ubuntu

最近在搭建Google的Cuttlefish这个开发环境,而该环境最好是在Ubuntu 20.04系统上搭建。电脑本来的系统是16.04的,根据网上的升级方法,使用命令升级,系统就是不提示升级。

最后,发现在如下的网址中,可以下载到各个版本的Ubuntu系统的升级工具。直接使用工具升级。

http://changelogs.ubuntu.com/meta-release

下载好工具解压之后,直接执行sudo ./XXX(XXX就是版本包中的Dist的同名文件,比如20.04就是sudo ./focal)

评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值