牙叔教程 简单易学
使用场景
控制台只显示指定级别的日志
但是日志文件里面显示所有日志
效果展示
autojs版本
8.7.7-0
get知识点
- 停止其他脚本
- 导入java类
- 获取控制台实例
- 获取日志实例
- 隐藏控制台输入框和按钮
- 遍历控制台view
- 重写控制台adapter
- 自定义控制台recycleView的布局
- 日志级别
- 退出事件
- 设置控制台大小和位置
原理
查看autojs开源代码, 可知日志构造函数如下
public LogEntry(int id, int level, CharSequence content) {
this.id = id;
this.level = level;
this.content = content;
this.content = content;
}
日志实体是有level属性的, 我们可以根据不同的level, 决定是否显示;
更进一步的话, 可以根据不同的level, 进行不同的显示, 比如不同的背景, 不同的字体颜色, 大小 等
其中, 最难的一步是获取日志数据, 这个需要反射, 相信对会java的同学, 信手拈来
代码讲解
1. 停止其他脚本
engines.all().map((ScriptEngine) => {
if (engines.myEngine().toString() !== ScriptEngine.toString()) {
ScriptEngine.forceStop();
}
});
2. 导入java类
importClass(Packages.androidx.recyclerview.widget.RecyclerView);
importClass(Packages.androidx.recyclerview.widget.LinearLayoutManager);
importClass(android.graphics.drawable.BitmapDrawable);
importClass(Packages.androidx.recyclerview.widget.DividerItemDecoration);
importClass(android.graphics.BitmapFactory);
importClass(android.graphics.Paint);
importClass(android.graphics.Color);
importClass(android.widget.LinearLayout);
3. 获取控制台需要处理的view
let mConsoleView = getConsoleWindow();
let parent = mConsoleView.parent;
var inputView = parent.findViewById(context.getResources().getIdentifier("input", "id", context.getPackageName()));
var buttonView = parent.findViewById(context.getResources().getIdentifier("submit", "id", context.getPackageName()));
var consoleView = parent.findViewById(context.getResources().getIdentifier("console", "id", context.getPackageName()));
4. 隐藏输入框和按钮
ui.run(function () {
inputView.setVisibility(8);
buttonView.setVisibility(8);
});
5. 获取控制台悬浮窗实例
function getConsoleWindow() {
var mConsole = runtime.console;
let field = mConsole.class.superclass.getDeclaredField("mConsoleFloaty");
field.setAccessible(true);
mConsoleFloaty = field.get(mConsole);
mConsoleView = mConsoleFloaty.getExpandedView();
return mConsoleView;
}
6. 修改控制台标题
let r = filterView(mConsoleView);
function filterView(view, arr) {
arr = arr || [];
if (view instanceof android.view.ViewGroup) {
arr.push(view);
let childCount = view.childCount;
for (var i = 0; i < childCount; i++) {
let chileView = view.getChildAt(i);
filterView(chileView, arr);
}
} else {
arr.push(view);
}
return arr;
}
7. 修改控制台标题
r[3].setText("牙叔教程 简单易学");
8. 控制台recycleview的子布局
let boxXml = (
);
9. 重写控制台adapter
ui.run(function () {
let recycleview = r[num];
function createAdapter(mLogEntries) {
return RecyclerView.Adapter({
onCreateViewHolder: function (parent, viewType) {
// 视图创建
let view;
let holder;
view = ui.inflate(boxXml, parent, false);
holder = JavaAdapter(RecyclerView.ViewHolder, {}, view);
return holder;
},
onBindViewHolder: function (holder, position) {
// 数据绑定
let logEntry = mLogEntries.get(position);
holder.itemView.setTextColor(colors.parseColor("#0000ff"));
holder.itemView.setText(logEntry.content);
let level = 5;
显示指定级别的日志(logEntry, holder, level);
},
getItemCount: function () {
return mLogEntries.size();
},
});
}
let newAdapter = createAdapter(mLogEntries);
recycleview.setAdapter(newAdapter);
});
10. 日志级别
static final SparseArray COLORS = new SparseArrayEntries()
.entry(Log.VERBOSE, 0xdfc0c0c0) 2
.entry(Log.DEBUG, 0xdfffffff) 3 log
.entry(Log.INFO, 0xff64dd17) 4
.entry(Log.WARN, 0xff2962ff) 5
.entry(Log.ERROR, 0xffd50000) 6
.sparseArray();
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途