[{"content":"代码正确，但是一直提示错误\nundefined reference to `PrintHandler::PrintHandler(Looper*)\u0026#39; collect2.exe: error: ld returned 1 exit status 无意中发现自己运行的是 main.cpp 而不是整个项目，运行整个项目就会正常了。\n具体原因见 AI\n这是一个 CLion 或 CMake 配置相关的问题，不是代码逻辑问题，而是你在运行 main.cpp 文件单独作为“单文件运行”时，编译器没有正确链接整个项目的所有 .cpp 文件（例如 Looper.cpp、PrintHandler.cpp 等），从而导致：\nundefined reference to `Looper::postMessage(...)` undefined reference to `vtable for PrintHandler` ... ✅ 原因详解 在 CLion 中点击右键运行 main.cpp 文件 时：\n它会临时生成一个只编译 main.cpp 的目标，没有链接你项目中定义的其他源文件（.cpp），所以报链接错误。\n而你点击的是：\n❌ 右键 main.cpp → Run main.cpp 只运行单文件，不会编译整个项目。\n✅ 正确做法 请始终使用：\n✅ Run 'EmployeeSystem' 或 Run '\u0026lt;your_target_name\u0026gt;' 也就是你在 CMakeLists.txt 中通过 add_executable() 定义的那个目标，例如：\nadd_executable(EmployeeSystem main.cpp Looper.cpp Message.cpp PrintHandler.cpp ... ) 在 CLion 里：\n点击右上角运行配置的下拉按钮，选择 EmployeeSystem\n或者点绿色小锤子和绿色三角形按钮来 Build / Run 项目\n✅ 避免误操作建议 你可以设置默认只运行 CMake 目标：\n打开 Run → Edit Configurations\n确保你运行的是 CMake Application 类型（不是 main.cpp）\n删除 main.cpp 的运行配置（避免误点）\n✅ 总结 操作后果✅ 运行整个项目（CMake目标）正常链接所有模块❌ 只运行 main.cpp缺少链接，报错\n你项目现在已经没问题了，只是 CLion 使用方式上的误区。后续只运行项目名对应的目标就不会出错了 ✅\n","permalink":"https://a6233.com/posts/clion-%E8%BF%90%E8%A1%8C%E6%8A%A5%E9%94%99%E8%A7%A3%E5%86%B3/","summary":"\u003cp\u003e代码正确，但是一直提示错误\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eundefined reference to `PrintHandler::PrintHandler(Looper*)\u0026#39;\ncollect2.exe: error: ld returned 1 exit status\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e无意中发现自己运行的是 main.cpp 而不是整个项目，运行整个项目就会正常了。\u003c/p\u003e\n\u003cp\u003e具体原因见 AI\u003c/p\u003e\n\u003cp\u003e这是一个 \u003cstrong\u003eCLion 或 CMake 配置相关的问题\u003c/strong\u003e，不是代码逻辑问题，而是\u003cstrong\u003e你在运行 \u003ccode\u003emain.cpp\u003c/code\u003e 文件单独作为“单文件运行”时，编译器没有正确链接整个项目的所有 \u003ccode\u003e.cpp\u003c/code\u003e 文件\u003c/strong\u003e（例如 \u003ccode\u003eLooper.cpp\u003c/code\u003e、\u003ccode\u003ePrintHandler.cpp\u003c/code\u003e 等），从而导致：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eundefined reference to `Looper::postMessage(...)`\nundefined reference to `vtable for PrintHandler`\n...\n\u003c/code\u003e\u003c/pre\u003e\u003chr\u003e\n\u003ch2 id=\"-原因详解\"\u003e✅ 原因详解\u003c/h2\u003e\n\u003cp\u003e在 \u003cstrong\u003eCLion 中点击右键运行 \u003ccode\u003emain.cpp\u003c/code\u003e 文件\u003c/strong\u003e 时：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e它会临时生成一个只编译 \u003ccode\u003emain.cpp\u003c/code\u003e 的目标，没有链接你项目中定义的其他源文件（\u003ccode\u003e.cpp\u003c/code\u003e），所以报链接错误。\u003c/p\u003e\n\u003cp\u003e而你点击的是：\u003c/p\u003e\n\u003ch3 id=\"-右键-maincpp--run-maincpp\"\u003e❌ \u003ccode\u003e右键 main.cpp → Run main.cpp\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e只运行单文件，不会编译整个项目。\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"-正确做法\"\u003e✅ 正确做法\u003c/h2\u003e\n\u003cp\u003e请始终使用：\u003c/p\u003e\n\u003ch3 id=\"-run-employeesystem-或-run-your_target_name\"\u003e✅ \u003ccode\u003eRun 'EmployeeSystem'\u003c/code\u003e 或 \u003ccode\u003eRun '\u0026lt;your_target_name\u0026gt;'\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e也就是你在 \u003ccode\u003eCMakeLists.txt\u003c/code\u003e 中通过 \u003ccode\u003eadd_executable()\u003c/code\u003e 定义的那个目标，例如：\u003c/p\u003e","title":"CLion 运行报错解决"},{"content":"解决方法 1、删除 icon 的缓存文件即可。 【Win】+【R】两个按键，打开【运行】输入%localappdata% 2、删除 Iconcache.db 文件 3、在系统管理器里重新启动 Window 资源管理器\n","permalink":"https://a6233.com/posts/window11-%E6%A1%8C%E9%9D%A2%E5%9B%BE%E6%A0%87%E5%8F%98%E7%99%BD%E5%A4%84%E7%90%86/","summary":"\u003ch3 id=\"解决方法\"\u003e解决方法\u003c/h3\u003e\n\u003cp\u003e1、删除 icon 的缓存文件即可。\n【Win】+【R】两个按键，打开【运行】输入%localappdata%\n2、删除 Iconcache.db 文件\n3、在系统管理器里重新启动 Window 资源管理器\u003c/p\u003e","title":"Window11 桌面图标变白处理"},{"content":"1、常用软件安装 obsidian\nvscode\ntypora\nchrome\n等等\n2、Java 安装和配置 sudo apt update sudo apt install openjdk-8-jdk sudo apt install openjdk-11-jdk java -version sudo update-alternatives --config java # 环境变量设置 sudo nano /etc/environment JAVA_HOME=\u0026#34;/usr/lib/jvm/java-11-openjdk-amd64\u0026#34; source /etc/environment echo $JAVA_HOME ","permalink":"https://a6233.com/posts/ubuntu-%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/","summary":"\u003ch3 id=\"1常用软件安装\"\u003e1、常用软件安装\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eobsidian\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003evscode\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003etypora\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003echrome\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e等等\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"2java-安装和配置\"\u003e2、Java 安装和配置\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo apt update\nsudo apt install openjdk-8-jdk\nsudo apt install openjdk-11-jdk\n\njava -version\n\nsudo update-alternatives --config java\n\n# 环境变量设置\nsudo nano /etc/environment\nJAVA_HOME=\u0026#34;/usr/lib/jvm/java-11-openjdk-amd64\u0026#34;\nsource /etc/environment\necho $JAVA_HOME\n\u003c/code\u003e\u003c/pre\u003e","title":"Ubuntu 开发环境配置"},{"content":"Ubuntu 手动添加应用快捷方式\n在 Ubuntu 20.04（或 20 系列）里创建桌面快捷方式，可以按照以下步骤操作：\n1. 创建 .desktop 文件 可以在桌面或者 ~/.local/share/applications/ 目录下新建一个 .desktop 文件，比如：\ngedit ~/Desktop/myapp.desktop 如果没有 gedit，你可以用 nano、vim，或者在文件管理器右键 -\u0026gt; 新建文档也可以。\n2. 填写内容模板 一般一个 .desktop 文件的内容是这样的：\n[Desktop Entry] Version=1.0 Name=应用名称 Comment=应用描述 Exec=命令或程序路径 Icon=图标路径 Terminal=false Type=Application Categories=Utility; Name：显示在图标下的名字\nComment：悬停时显示的提示文字\nExec：启动程序的命令或脚本路径\nIcon：图标路径（可以用 .png 或 .svg 图片）\nTerminal：是否需要终端窗口运行，通常设为 false\nType：通常是 Application\nCategories：可以简单填个 Utility;，不影响桌面启动\n举个例子，比如你要给 Chrome 浏览器创建快捷方式：\n[Desktop Entry] Version=1.0 Name=Google Chrome Comment=浏览器 Exec=/usr/bin/google-chrome-stable Icon=/usr/share/icons/hicolor/128x128/apps/google-chrome.png Terminal=false Type=Application Categories=Network; 3. 给文件加执行权限 chmod +x ~/Desktop/myapp.desktop 不加权限的话，桌面图标点了会没反应或者提示“不受信任的应用程序”。\n4. 信任桌面文件（如果需要） 有时候即使加了执行权限，Ubuntu 桌面也会弹窗警告。这时你可以右键 .desktop 文件，选择 允许启动（Allow Launching）。\n补充： 如果是自己写的程序，可以把 Exec 写成 bash /path/to/your/script.sh\n图标路径如果找不到，可以自己随便用一张图，或者用系统自带的 /usr/share/icons/ 下的图。\n如果要添加到 开始菜单（应用程序菜单），就把 .desktop 文件放到 ~/.local/share/applications/ 里。\n","permalink":"https://a6233.com/posts/ubuntu-%E6%89%8B%E5%8A%A8%E6%B7%BB%E5%8A%A0%E5%BA%94%E7%94%A8%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F/","summary":"\u003cp\u003eUbuntu 手动添加应用快捷方式\u003c/p\u003e\n\u003cp\u003e在 Ubuntu 20.04（或 20 系列）里创建桌面快捷方式，可以按照以下步骤操作：\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"1-创建-desktop-文件\"\u003e1. 创建 \u003ccode\u003e.desktop\u003c/code\u003e 文件\u003c/h3\u003e\n\u003cp\u003e可以在桌面或者 \u003ccode\u003e~/.local/share/applications/\u003c/code\u003e 目录下新建一个 \u003ccode\u003e.desktop\u003c/code\u003e 文件，比如：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egedit ~/Desktop/myapp.desktop\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e如果没有 \u003ccode\u003egedit\u003c/code\u003e，你可以用 \u003ccode\u003enano\u003c/code\u003e、\u003ccode\u003evim\u003c/code\u003e，或者在文件管理器右键 -\u0026gt; 新建文档也可以。\u003c/p\u003e\n\u003ch3 id=\"2-填写内容模板\"\u003e2. 填写内容模板\u003c/h3\u003e\n\u003cp\u003e一般一个 \u003ccode\u003e.desktop\u003c/code\u003e 文件的内容是这样的：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e[Desktop Entry]\nVersion=1.0\nName=应用名称\nComment=应用描述\nExec=命令或程序路径\nIcon=图标路径\nTerminal=false\nType=Application\nCategories=Utility;\n\u003c/code\u003e\u003c/pre\u003e\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eName\u003c/code\u003e：显示在图标下的名字\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eComment\u003c/code\u003e：悬停时显示的提示文字\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eExec\u003c/code\u003e：启动程序的命令或脚本路径\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eIcon\u003c/code\u003e：图标路径（可以用 \u003ccode\u003e.png\u003c/code\u003e 或 \u003ccode\u003e.svg\u003c/code\u003e 图片）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eTerminal\u003c/code\u003e：是否需要终端窗口运行，通常设为 \u003ccode\u003efalse\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eType\u003c/code\u003e：通常是 \u003ccode\u003eApplication\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eCategories\u003c/code\u003e：可以简单填个 \u003ccode\u003eUtility;\u003c/code\u003e，不影响桌面启动\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e举个例子，比如你要给 Chrome 浏览器创建快捷方式：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e[Desktop Entry]\nVersion=1.0\nName=Google Chrome\nComment=浏览器\nExec=/usr/bin/google-chrome-stable\nIcon=/usr/share/icons/hicolor/128x128/apps/google-chrome.png\nTerminal=false\nType=Application\nCategories=Network;\n\u003c/code\u003e\u003c/pre\u003e\u003chr\u003e\n\u003ch3 id=\"3-给文件加执行权限\"\u003e3. 给文件加执行权限\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003echmod +x ~/Desktop/myapp.desktop\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e不加权限的话，桌面图标点了会没反应或者提示“不受信任的应用程序”。\u003c/p\u003e","title":"Ubuntu 手动添加应用快捷方式"},{"content":"requestLayout() 和 invalidate() 是 Android 中 View 类的两个重要方法，用于不同的视图更新场景。让我解释它们的作用和区别：\nrequestLayout() 方法 作用：\n请求重新测量和布局整个视图树。\n触发视图的 onMeasure() 和 onLayout() 方法。\n用于视图的大小或位置发生变化时。\n调用时机：\n当视图的尺寸需要改变时。\n当视图的位置需要改变时。\n当视图的子视图发生增删或其布局参数变化时。\n例子：\nbutton.setVisibility(View.GONE); parentLayout.requestLayout(); invalidate() 方法 作用：\n请求重绘视图。\n触发视图的 onDraw() 方法。\n用于视图的内容或外观需要更新，但尺寸和位置不变时。\n调用时机：\n当视图的颜色、文本内容等发生变化时。\n当需要重新绘制自定义视图的内容时。\n动画更新时。\n例子：\ntextView.setTextColor(Color.RED); textView.invalidate(); 主要区别：\n影响范围：\nrequestLayout(): 可能影响整个视图层次结构的布局。\ninvalidate(): 通常只影响调用它的视图及其子视图。\n性能影响：\nrequestLayout(): 开销较大，因为它可能导致整个视图树的重新测量和布局。\ninvalidate(): 开销相对较小，通常只涉及重绘。\n触发的回调：\nrequestLayout(): 触发 onMeasure() 和 onLayout()，可能还会触发 onDraw()。\ninvalidate(): 主要触发 onDraw()。\n使用场景：\nrequestLayout(): 用于影响视图结构或尺寸的变化。\ninvalidate(): 用于视图内容或外观的更新。\n线程安全：\nrequestLayout(): 可以在非 UI 线程调用。\ninvalidate(): 只能在 UI 线程调用。（非 UI 线程应使用 postInvalidate()）\n实际使用示例：\npublic class CustomView extends View { private int mColor; public void setColor(int color) { mColor = color; invalidate(); // 只需要重绘 } public void setNewSize(int width, int height) { getLayoutParams().width = width; getLayoutParams().height = height; requestLayout(); // 需要重新测量和布局 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 使用 mColor 绘制 } } 在这个例子中，改变颜色只需要 invalidate()，而改变尺寸则需要 requestLayout()。\n理解这两个方法的区别和适用场景对于优化 Android 应用的性能和创建响应式 UI 非常重要。如果你想了解更多关于如何在复杂场景中使用这些方法，或者需要更多的代码示例，我可以为你提供更详细的信息。\n","permalink":"https://a6233.com/posts/requestlayout-%E5%92%8C-invalidate-%E4%BD%9C%E7%94%A8/","summary":"\u003cp\u003e\u003ccode\u003erequestLayout()\u003c/code\u003e 和 \u003ccode\u003einvalidate()\u003c/code\u003e 是 Android 中 View 类的两个重要方法，用于不同的视图更新场景。让我解释它们的作用和区别：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003erequestLayout() 方法\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e作用：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e请求重新测量和布局整个视图树。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e触发视图的 onMeasure() 和 onLayout() 方法。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e用于视图的大小或位置发生变化时。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e调用时机：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e当视图的尺寸需要改变时。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e当视图的位置需要改变时。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e当视图的子视图发生增删或其布局参数变化时。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e例子：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ebutton.setVisibility(View.GONE);\nparentLayout.requestLayout();\n\u003c/code\u003e\u003c/pre\u003e\u003cul\u003e\n\u003cli\u003einvalidate() 方法\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e作用：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e请求重绘视图。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e触发视图的 onDraw() 方法。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e用于视图的内容或外观需要更新，但尺寸和位置不变时。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e调用时机：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e当视图的颜色、文本内容等发生变化时。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e当需要重新绘制自定义视图的内容时。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e动画更新时。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e例子：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003etextView.setTextColor(Color.RED);\ntextView.invalidate();\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e主要区别：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e影响范围：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003erequestLayout(): 可能影响整个视图层次结构的布局。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003einvalidate(): 通常只影响调用它的视图及其子视图。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e性能影响：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003erequestLayout(): 开销较大，因为它可能导致整个视图树的重新测量和布局。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003einvalidate(): 开销相对较小，通常只涉及重绘。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e触发的回调：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003erequestLayout(): 触发 onMeasure() 和 onLayout()，可能还会触发 onDraw()。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003einvalidate(): 主要触发 onDraw()。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用场景：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003erequestLayout(): 用于影响视图结构或尺寸的变化。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003einvalidate(): 用于视图内容或外观的更新。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e线程安全：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003erequestLayout(): 可以在非 UI 线程调用。\u003c/p\u003e","title":"requestLayout() 和 invalidate() 作用"},{"content":"配置 python\n安装了 python2 后默认可以使用命令python2 来执行操作，但是一些脚本使用的是python，所以这样会导致脚本执行错误：python: command not found。\n这样就需要我们python关联到python2上面。我们可以借助update-alternatives来实现。\n比如上面的情况，我们可以设置命令如下。\nsudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2 这里面的 python3 看情况而定，这里只是演示。\n接着我们就可以使用命令切换我们需要使用的版本了。\nsudo update-alternatives --config python 配置 Java 同样我们也可以如法炮制来配置jdk的版本。\nsudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1 sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-11-openjdk-amd64/bin/java 2 ​ 接着选择我们使用的版本即可。\nsudo update-alternatives \u0026ndash;config java\n","permalink":"https://a6233.com/posts/%E7%BC%96%E8%AF%91-android-%E6%BA%90%E7%A0%81%E6%89%BE%E4%B8%8D%E5%88%B0-python-%E6%96%B9%E6%B3%95%E8%A7%A3%E5%86%B3%E8%AE%B0%E5%BD%95/","summary":"\u003cp\u003e配置 python\u003c/p\u003e\n\u003cp\u003e安装了 python2 后默认可以使用命令\u003ccode\u003epython2\u003c/code\u003e 来执行操作，但是一些脚本使用的是\u003ccode\u003epython\u003c/code\u003e，所以这样会导致脚本执行错误：\u003ccode\u003epython: command not found\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e这样就需要我们\u003ccode\u003epython\u003c/code\u003e关联到\u003ccode\u003epython2\u003c/code\u003e上面。我们可以借助\u003ccode\u003eupdate-alternatives\u003c/code\u003e来实现。\u003c/p\u003e\n\u003cp\u003e比如上面的情况，我们可以设置命令如下。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1\nsudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这里面的 python3 看情况而定，这里只是演示。\u003c/p\u003e\n\u003cp\u003e接着我们就可以使用命令切换我们需要使用的版本了。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo update-alternatives --config python\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"配置-java\"\u003e配置 Java\u003c/h3\u003e\n\u003cp\u003e同样我们也可以如法炮制来配置\u003ccode\u003ejdk\u003c/code\u003e的版本。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1\nsudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-11-openjdk-amd64/bin/java 2\n​\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e接着选择我们使用的版本即可。\u003c/p\u003e\n\u003cp\u003esudo update-alternatives \u0026ndash;config java\u003c/p\u003e","title":"编译 android 源码找不到 python 方法解决记录"},{"content":"1、提示 BaseTools C Tool binary was not found\nBaseTools C Tool binary was not found (GenFw) You may need to run: 可以到提示的目录下，执行 make 编译即可。\n","permalink":"https://a6233.com/posts/%E7%BC%96%E8%AF%91-android-%E6%BA%90%E7%A0%81%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E8%AE%B0%E5%BD%95/","summary":"\u003cp\u003e1、提示 BaseTools C Tool binary was not found\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eBaseTools C Tool binary was not found (GenFw)\nYou may need to run:\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e可以到提示的目录下，执行 make 编译即可。\u003c/p\u003e","title":"编译 android 源码错误解决记录"},{"content":"在 AndroidManifest.xml 文件中，\u0026lt;uses-library\u0026gt; 标签用于声明应用程序依赖于某个外部库。这些库通常是Android系统提供的可选库，而不是应用自身打包的库。通过声明 \u0026lt;uses-library\u0026gt;，你可以确保系统在应用安装时检查该库是否可用，并在缺少该库时阻止应用安装或运行。\n常见的用途有依赖某些系统扩展库或平台库，例如 org.apache.http.legacy，可以通过 \u0026lt;uses-library\u0026gt; 声明这个依赖关系：\n\u0026lt;uses-library android:name=\u0026#34;org.apache.http.legacy\u0026#34; android:required=\u0026#34;false\u0026#34; /\u0026gt; 属性解释：\nandroid:name: 指定依赖库的名称。\nandroid:required: 可选属性，默认为 true，表示该库是必需的。如果设置为 false，即使设备上没有该库，应用仍然可以运行，只不过相关功能可能无法使用。\n这个声明在处理不同版本的系统或与系统扩展库集成时非常有用。\n","permalink":"https://a6233.com/posts/uses-library-%E6%A0%87%E7%AD%BE%E4%BD%9C%E7%94%A8/","summary":"\u003cp\u003e在 \u003ccode\u003eAndroidManifest.xml\u003c/code\u003e 文件中，\u003ccode\u003e\u0026lt;uses-library\u0026gt;\u003c/code\u003e 标签用于声明应用程序依赖于某个外部库。这些库通常是Android系统提供的可选库，而不是应用自身打包的库。通过声明 \u003ccode\u003e\u0026lt;uses-library\u0026gt;\u003c/code\u003e，你可以确保系统在应用安装时检查该库是否可用，并在缺少该库时阻止应用安装或运行。\u003c/p\u003e\n\u003cp\u003e常见的用途有依赖某些系统扩展库或平台库，例如 \u003ccode\u003eorg.apache.http.legacy\u003c/code\u003e，可以通过 \u003ccode\u003e\u0026lt;uses-library\u0026gt;\u003c/code\u003e 声明这个依赖关系：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\u0026lt;uses-library\n    android:name=\u0026#34;org.apache.http.legacy\u0026#34;\n    android:required=\u0026#34;false\u0026#34; /\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e属性解释：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eandroid:name\u003c/code\u003e: 指定依赖库的名称。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eandroid:required\u003c/code\u003e: 可选属性，默认为 \u003ccode\u003etrue\u003c/code\u003e，表示该库是必需的。如果设置为 \u003ccode\u003efalse\u003c/code\u003e，即使设备上没有该库，应用仍然可以运行，只不过相关功能可能无法使用。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e这个声明在处理不同版本的系统或与系统扩展库集成时非常有用。\u003c/p\u003e","title":"\u003cuses-library\u003e \u003c/uses-library\u003euses-library \u003cuses-library\u003e标签\u003c/uses-library\u003e作用"},{"content":"要从 Git 中移除已跟踪的文件，同时保持这些文件在本地存在（不删除本地文件），你可以按照以下步骤操作：\n更新 .gitignore 文件：确保你已经正确配置了你想忽略的文件或目录。\n移除文件的追踪：使用 git rm --cached 来移除已追踪的文件。\ngit rm -r --cached \u0026lt;file_or_directory\u0026gt; 例如，如果你想移除 .log 文件的追踪：\ngit rm -r --cached *.log 提交更改：移除追踪后需要提交这些更改。 git commit -m \u0026#34;移除已追踪的文件，更新 .gitignore\u0026#34; 推送更改（如果有远程仓库）： git push origin \u0026lt;branch_name\u0026gt; 执行以上步骤后，Git 将停止追踪 .gitignore 中定义的文件或目录，但这些文件仍然会保留在你的本地文件系统中。\n","permalink":"https://a6233.com/posts/git-%E5%8F%96%E6%B6%88%E8%B7%9F%E8%B8%AA%E6%96%87%E4%BB%B6/","summary":"\u003cp\u003e要从 Git 中移除已跟踪的文件，同时保持这些文件在本地存在（不删除本地文件），你可以按照以下步骤操作：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e更新 \u003ccode\u003e.gitignore\u003c/code\u003e 文件\u003c/strong\u003e：确保你已经正确配置了你想忽略的文件或目录。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e移除文件的追踪\u003c/strong\u003e：使用 \u003ccode\u003egit rm --cached\u003c/code\u003e 来移除已追踪的文件。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit rm -r --cached \u0026lt;file_or_directory\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e例如，如果你想移除 \u003ccode\u003e.log\u003c/code\u003e 文件的追踪：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit rm -r --cached *.log\n\u003c/code\u003e\u003c/pre\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e提交更改\u003c/strong\u003e：移除追踪后需要提交这些更改。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit commit -m \u0026#34;移除已追踪的文件，更新 .gitignore\u0026#34;\n\u003c/code\u003e\u003c/pre\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e推送更改\u003c/strong\u003e（如果有远程仓库）：\u003c/li\u003e\n\u003c/ul\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003egit push origin \u0026lt;branch_name\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e执行以上步骤后，Git 将停止追踪 \u003ccode\u003e.gitignore\u003c/code\u003e 中定义的文件或目录，但这些文件仍然会保留在你的本地文件系统中。\u003c/p\u003e","title":"Git 取消跟踪文件"}]