牙叔教程 简单易学
使用场景
控制台只显示指定级别的日志
但是日志文件里面显示所有日志
效果展示
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 = ( <TextView id="content" layout_width="match_parent" layout_height="wrap_content" textIsSelectable="true" textSize="19sp" margin="6" ></TextView> );
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<Integer> COLORS = new SparseArrayEntries<Integer>() .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();
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途