找回Ubuntu16.04中nautilus输入文字快速定位文件功能

16.04的版本中nautilus文件管理器有一项快速定位文件的功能非常好用直接在文件夹中打出首字母即可快速定位到文件,但是在18.04以上的版本中默认就取消了这项功能使得我迁移到新版本中非常不适应今天碰巧找到了找回这个功能的办法记录一下:

  1. 第一种安装第三方插件
    1
    2
    3
    sudo add-apt-repository ppa:lubomir-brindza/nautilus-typeahead
    sudo apt dist-upgrade
    nautilus -r
  2. 第二种调整配置文件
    先安装dconf工具 sudo apt install dconf-editor
    打开dconf-editor找到org -> gnome -> nautilus -> preferences -> enable-interactive-search 打钩即可

解决Android Studio missing essential plugin org.jetbrains.android

最近把Android Studio升级到了4.1.1版本之前安装了一个smailidea的插件老是报不兼容于是强迫症的我手贱了一下把插件给禁用了,禁用的时候没注意把依赖的一些东西也给禁用了于是报了下面的错误

这是禁用插件时候的依赖提示

可以看见其实把很多核心的组件都给禁用了那怎么办呢?难不成真的要按提示上说的要重装Android Studio?不要慌问题不大其实还有一种办法就是把被禁用的插件恢复就可以了,大家可以把Android Studio的配置目录的disabled_plugins.txt这个文件删除这样Android Studio就可以正常启动了, 这个文件每个系统存放的位置不太一样一般都在下面这几个目录 如果不在可以在主目录全局搜索一下这个文件

Windows: C:\Users\%USERNAME%\AndroidStudio4.1\config

Linux: ~/.config/Google/AndroidStudio4.1

MacOS: ~/Library/Application Support/Google/AndroidStudio4.1

如何获得一个垂直的SeekBar

小记

在开发”上帝模式”的一个新功能中偶然需要用到一个垂直的SeekBar,一开始想得比较简单系统应该有提供这样垂直的SeekBar但是翻了一下SDK并没有于是上网搜索,查找下来无非这两种:

  1. 使用原生的SeekBar旋转90度
  2. 自定义SeekBaronDraw方法和onMeasure方法中旋转画布并重新计算控件大小

那为什么有两种呢让我们来分别分析一下这两个方案的优缺点:

  • 第一种使用原生的SeekBar最简单但是旋转后的宽高就不对了,实际上的宽是旋转后的高这也导致如果我们要增加SeekBar的高度就需要修改宽度但是会导致布局错乱以下是旋转前后对比:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <SeekBar
    android:id="@+id/seekbar1"
    android:layout_width="120dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:clickable="true"
    android:layoutDirection="rtl"/>

    <SeekBar
    android:id="@+id/seekbar2"
    android:layout_width="120dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:clickable="true"
    android:layoutDirection="rtl"
    android:rotation="90"/>
阅读更多...

ByteBuffer详解

之前对NIO开发不熟悉导致对ByteBuffer一直是一知半解的状态正好看到知乎上有个朋友写的不错于是转载过来

转自:https://zhuanlan.zhihu.com/p/56876443

在Java nio中,主要有三大组件:Buffer,Channel和Selector。这三者之间的关系可以按照如下方式进行理解:

  • Buffer提供了一个字节缓冲区,其可以不断的从Channel中读取接收到的数据。Buffer的优点主要在于其提供了一系列的Api,能够让用户更方便的对数据进行读取和写入;
  • Channel简单来说就是一个信道,也就是客户端与服务器的一个连接,而且每个客户端都会对应一个Channel对象;
  • Selector是Java nio能够支持高并发数据处理一个关键,其核心理念就是IO多路复用的原理,简单的说就是当多个客户端(Channel)连接服务器时,可以通过Selector同时对这些客户端请求进行监听,当客户端发送数据到服务器之后由Selector对这些Channel进行分发处理。

本文首先讲解ByteBuffer的实现原理,然后会介绍ByteBuffer中常用的Api,以及其在使用过程中需要注意的点。

  1. 实现原理
    对于ByteBuffer,其主要有五个属性:mark,position,limit,capacity和array。这五个属性的作用如下:

    • mark:记录了当前所标记的索引下标;
    • position:对于写入模式,表示当前可写入数据的下标,对于读取模式,表示接下来可以读取的数据的下标;
    • limit:对于写入模式,表示当前可以写入的数组大小,默认为数组的最大长度,对于读取模式,表示当前最多可以读取的数据的位置下标;
    • capacity:表示当前数组的容量大小;
    • array:保存了当前写入的数据。

    这几个数据中,除了array是用于保存数据的以外,这里最终的主要是position,limit和capacity三个属性,因为对于写入和读取模式,这三个属性的表示的含义大不一样。

    阅读更多...

Xposed为何对京东无法生效

前一阵子对京东的一个功能比较好奇于是就有了逆向京东的想法,我熟练的拿起了jadx对京东进行反编译居然没有混淆心中狂喜很快就找到入口点,于是又祭出了Xposed大法飞快的写了个插件Hook了ActivityonCreate方法,我迫不及待的跑了起来结果hook貌似没有生效任何Log都没有输出,反复检查后仍不得其解不过此时的我已心中暗暗猜测京东应该有一些反Xposed的机制,因为之前曾见过”酷安”和”知乎”也有这样的功能,于是又Hook了像Class.forName ClassLoader.loadClass这样的函数来验证一下我的想法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook()
{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable
{
if(((String)param.args[0]).startsWith("de.robv.android.xposed"))
{
Log.d("Kaisar", "loadclass:" + Arrays.toString(param.args), new Throwable());
param.setThrowable(new ClassNotFoundException());
}
}
});
XposedHelpers.findAndHookMethod(Class.class, "forName", String.class, new XC_MethodHook()
{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable
{
if(((String)param.args[0]).startsWith("de.robv.android.xposed"))
{
Log.d("Kaisar", "forName:" + Arrays.toString(param.args), new Throwable());
param.setThrowable(new ClassNotFoundException());
}
}
});
阅读更多...

InputStream无法与BufferReader同时用

​ 前两天客户端这边有一块业务一开始想的是用socket直接跟后端传数据,后来后端觉得基于目前的框架改太麻烦于是协商了一下还是改为HTTP协议,我一想HTTP传过来过我把HTTP的头给忽略掉不就可以了于是直接动手撸了个HTTP服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Socket socket = serverSocket.accept();

BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
LinkedHashMap<String, String> headerFields = new LinkedHashMap<String, String>();
for(String header; (header = r.readLine()) != null && !header.isEmpty();){
//解析HTTP头
...
}

System.out.println(header)

int length = Integer.parseInt(headerFields.get("Content-Length"));
byte[] buffer = new byte[length];
socket.getInputStream().read(buffer);
//处理业务数据
...

OutputStream out = socket.getOutputStream();
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("\r\n".getBytes());
out.write("fuck you\r\n").getBytes());
out.flush();
socket.close();
阅读更多...

使用openstf部署一套内部测试平台

安装环境

安装openstf

  1. sudo docker pull rethinkdb:latest # 拉取rethinkdb 镜像
  2. sudo docker pull sorccu/adb:latest # 拉取android adb 镜像
  3. sudo docker pull devicefarmer/stf:latest #拉取openstf 镜像

部署openstf

openstf部署方式有两种

  1. 集中管理: openstf管理平台所连接的设备在一台机器上

1
2
3
$ docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090
$ docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest
$ docker run -d --name stf --net host devicefarmer/stf stf local --public-ip ${你的ip}
  • 优点:简单快捷适合小规模部署
  • 缺点:不够灵活且单台机器挂载能有限
  1. 分布式管理: openstf提供了provider模式可以用来进行分布式部署

需要准备两台机器A,B 在机器A上部署OpenSTF管理平台

1
2
3
$ docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090
$ docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest
$ docker run -d --name stf --net host devicefarmer/stf stf local --public-ip ${你的ip} --bind-dev-pub="tcp://0.0.0.0:7114" --bind-dev-pull="tcp://0.0.0.0:7116" --allow-remote

注意事项:

1
--bind-dev-pub="tcp://0.0.0.0:7114" --bind-dev-pull="tcp://0.0.0.0:7116"

这行一定要加否则服务将监听在127.0.0.1地址上会导致provider节点无法连接之前没加导致排查了很久

在机器B上部署Provider节点

1
2
$ docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest
$ docker run -d --name stf --net host devicefarmer/stf stf provider --connect-sub tcp://${机器A的IP}:7114 --connect-push tcp://${机器A的IP}:7116 --public-ip ${机器A的IP} --storage-url http://${机器A的IP}:7100/
  • 优点:灵活且理论支持无限拓展连接设备
  • 缺点:配置略微复杂

部署好后访问安装OpenSTF管理平台机器的ip地址加端口7100,如http://192.168.1.1:7100

不通过文件转储直接从adb shell读取stdout数据

通常我们从Android设备中捕获当前UI界面信息使用以下命令:

1
2
adb shell uiautomator dump /sdcard/screen.xml
adb pull /sdcard/screen.xml

在上面的代码块中我们经历了两个步骤

  1. 执行命令结果输出到/sdcard/screen.xml

  2. 拉取设备上的文件

从效率上来看是很慢的那有没有比较快的办法呢? 答案是有的!
我们可以利用/dev/tty设备让它直接输出到stdout上这样就省去文件转储了

1
adb shell uiautomator dump /dev/tty

你满怀期待着等着结果只看到

1
UI hierchary dumped to: /dev/tty

WTF? 这是什么鬼dump出来的信息去哪了?眉头一紧事情好像貌似没有这么简单…
经过一番研究发现我们使用的adb shell会将命令输出发给pty经过一顿骚操作pty把数据搞丢了,所以在新版的adb中引入了一个新的功能exec-out该参数可以将二进制数据直接原封不动的输出。详情请参考

所以只需要将命令改成这样即可:

1
adb exec-out 'uiautomator dump /dev/tty 1>/dev/null'

如何远程调试一台Android设备

要想跨越公网调试Android设备首先需要解决两个问题:

  1. 如何让adb走tcp通信
  2. 如何从公网连接这台设备

第一个问题:通过tcp调试Android手机

其实adb本身是支持通过tcp协议传输数据的只是可能大部分人从来没用过这个功能,大家可以在终端里面输入adb –help查看,里面有这么几个参数:

1
2
3
4
5
6
7
...
networking:
connect HOST[:PORT] connect to a device via TCP/IP
disconnect [[HOST]:PORT] disconnect from given TCP/IP device, or all
...
usb restart adbd listening on USB
tcpip PORT restart adbd listening on TCP on PORT

connect和disconnect是用来连接一台远程设备或者断开远程设备的,usb和tcpip选项是用来切换手机端adbd守护进程工作模式的我们要用到的就是tcpip这个参数使adbd服务监听在一个特定的网络端口上

在电脑端执行

1
2
3
adb shell ifconfig wlan0 #先查看一下手机wifi的ip地址后续连接的时候会用到
adb tcpip 5555 #将手机切换到tcp模式并在5555端口上监听
adb connect 192.168.1.8:5555 #连接手机对应的ip地址和端口

或者在已root的设备上使用termux软件设置adbd为tcp模式

1
2
3
4
5
6
7
// 持久化设置
# setprop persist.adb.tcp.port 5555
# stop adbd; start adbd
// 一次性设置重启后失效
# setprop service.adb.tcp.port 5555
# stop adbd; start adbd

至此第一个问题已解决

阅读更多...
  • Copyrights © 2015-2025 Kaisar
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信