0%

Jadx添加全局搜索一键导出功能

背景

项目中是模块化后, 各个模块和很多依赖库都是以aar的形式存在,有时我们想快速的去搜索整个项目中调用某个方法的调用,我们首先想到的是用jadx,但是jadx只能帮我们搜索到引用某个方法的代码,而没有导出功能,此文档为拓展jadx新增了一个导出功能

eg:

打开jadx,全局搜索”start(“,点击export

导出到user.home 目录

excel打开csv文件

下载

https://github.com/skylot/jadx

1
git clone git@github.com:skylot/jadx.git

修改

jadx/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   protected JPanel initResultsTable() {
...

JButton nextPageButton = new JButton("->");
nextPageButton.setToolTipText(NLS.str("search_dialog.next_page"));
nextPageButton.addActionListener(e -> {
if (resultsModel.nextPage()) {
switchPage(renderer);
}
});

JButton prevPageButton = new JButton("<-");
prevPageButton.setToolTipText(NLS.str("search_dialog.prev_page"));
prevPageButton.addActionListener(e -> {
if (resultsModel.prevPage()) {
switchPage(renderer);
}
});

paginationPanel.add(prevPageButton);
paginationPanel.add(nextPageButton);
paginationPanel.add(resultsInfoLabel);

//-----------------------------------
//这部分代码为我们自己添加
JButton exportButton = new JButton("export");
exportButton.setToolTipText("导出");
exportButton.addActionListener( e -> {
if(resultsModel.getResultCount() > 0){
CvsExport.export(resultsModel.getRows());
}
});
paginationPanel.add(exportButton);
//-----------------------------------
resultsPanel.add(paginationPanel);
resultsPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
return resultsPanel;
}

添加依赖 jadx/jadx-gui/build.gradle

1
implementation group: 'net.sourceforge.javacsv', name: 'javacsv', version: '2.0'

导出csv逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CvsExport {
public static void export(List<JNode> jList) {
try {
String userHome = System.getProperty("user.home");
String path_code = userHome+ "/search-code.csv";
CsvWriter csvWriter = new CsvWriter(path_code, ',', Charset.forName("GBK"));
csvWriter.writeRecord(new String[]{"Class","Node","Code","备注"});

for (JNode o : jList) {
if(o.toString().toLowerCase().contains("android.support")){
continue;
}
if(o instanceof CodeNode) {
csvWriter.writeRecord(new String[]{o.getJParent().getCls().toString(),o.toString(),((CodeNode) o).getLineStr().toString(),""});
}
}
csvWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

编译

1
2
cd jadx
./gradlew dist

导出产物

Class Node Code
androidx.appcompat.app.AppCompatActivity androidx.appcompat.app.AppCompatActivity.onStart() void public void onStart() {
androidx.appcompat.app.AppCompatActivity androidx.appcompat.app.AppCompatActivity.onStart() void super.onStart();
androidx.appcompat.app.AppCompatActivity androidx.appcompat.app.AppCompatActivity.onStart() void getDelegate().onStart();
androidx.appcompat.app.AppCompatDelegate androidx.appcompat.app.AppCompatDelegate.onStart() void public abstract void onStart();
androidx.appcompat.app.AppCompatDelegateImpl androidx.appcompat.app.AppCompatDelegateImpl.onStart() void public void onStart() {