首页 文章 精选 留言 我的

精选列表

搜索[分享平台],共10003篇文章
优秀的个人博客,低调大师

Android -- 经验分享

目录 代码中安装apk 判断某个apk是否已经安装 取得屏幕大小 获得 LayoutInflater 实例的三种方式 ContentResolver.query(),以及 Activity.managedQuery异同 解锁功能 点亮屏幕 activity全屏显示 屏常亮代码 SQL中 inner join、 left join 、right join、 outer join之间的区别 包含button的item也能弹出菜单,回调click以及long click的监听器 背光亮度 /sys/class/leds/lcd-backlight/brightness 判断是否在锁屏界面的函数 OnTouchListener实现双击事件 回到待机界面 定时器相关 sd卡和sim卡状态判断 开机启动,检查sim卡是否发生变更 代码中安装apk Runtime.getRuntime().exec("pm install xxx.apk"); 需要在manifest.xml文件中,加上INSTALL_PACKAGES的权限,可以用 Package install的receiver来处理安装成功后的操作 或者: /** * 安装apk * @param url */ private void installApk(String saveFileName){ File apkfile = new File(saveFileName); if (!apkfile.exists()) { return; } Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(i); } 判断某个APK是否已经安装 private boolean isAppInstalled(String uri){ PackageManager pm = getPackageManager(); boolean installed =false; try{ pm.getPackageInfo(uri,PackageManager.GET_ACTIVITIES); installed =true; }catch(PackageManager.NameNotFoundException e){ installed =false; } return installed; } //Just call the method by passing the package name of the application you need to check. if(isAppInstalled("com.yourpackage.package")){ //app installed }else{ //app not installed } 取得屏幕大小 1、在非activity类中 WindowManager windowManager = (WindowManager)(mContext.getSystemService(Context.WINDOW_SERVICE)); int screenWidth = windowManager.getDefaultDisplay().getWidth(); int screenHeight = windowManager.getDefaultDisplay().getHeight(); 2、在activity类中 int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px) int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,如:800px) 获得 LayoutInflater 实例的三种方式 LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater() LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater inflater = LayoutInflater.from(context); 示意代码: LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test)); 对于上面代码,指定了第二个参数 ViewGroup root,当然你也可以设置为 null 值。 ContentResolver.query(),以及 Activity.managedQuery异同 参数、返回值相同:都返回 Cursor 对象 参数: URI: Content Provider 需要返回的资源索引 Projection: 用于标识有哪些columns需要包含在返回数据中。 Selection: 作为查询符合条件的过滤参数,类似于SQL语句中Where之后的条件判断。 SelectionArgs: 同上。 SortOrder: 用于对返回信息进行排序。 不同: mContext.getContentResolver().query ContentResolver.query(),以及 Activity.managedQuery()所以,我们看到一个是ContentResolver提供的查询方法,位于android.content.ContextWrapper.getContentResolver(),另一个则为Activity。 Activity.managedQuery() 方法导致活动管理 Cursor 的生命周期 解锁功能 KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE); KeyguardLock keyguardLock = keyguardManager.newKeyguardLock(""); keyguardLock.disableKeyguard(); PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); 点亮屏幕 PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); WakeLock mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK,"SimpleTimer"); mWakeLock.acquire();//点亮 mWakeLock.release();//关闭 activity全屏显示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); 注意;要在setContentView(R.layout.layout)语句之前调用才行。 屏常亮代码 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//屏常亮 SQL中 inner join、 left join 、right join、 outer join之间的区别 举例说明 A表(a1,b1,c1) B表(a2,b2) a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 03 英语 80 04 王五 select A.*,B.* from A inner join B on(A.a1=B.a2) 结果是: a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 select A.*,B.* from A left outer join B on(A.a1=B.a2) 结果是: a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 03 英语 80 NULL NULL select A.*,B.* from A right outer join B on(A.a1=B.a2) 结果是: a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 NULL NULL NULL 04 王五 select A.*,B.* from A full outer join B on(A.a1=B.a2) 结果是: a1 b1 c1 a2 b2 01 数学 95 01 张三 02 语文 90 02 李四 03 英语 80 NULL NULL NULL NULL NULL 04 王五 包含button的item也能弹出菜单,回调click以及long click的监听器 设置button属性: android:focusable="false" 外还要设置 listview属性: android:longClickable="true" PS: 如果包含的Button是ImageButton,那么在xml中设置了android:focusable="false"属性在当前版本是无效的,必须在代码中,再次呼叫函数ImageButton.setFocusable(false)设置一次。 或者在父Item里面加上 android:descendantFocusability="blocksDescendants" 背光亮度 /sys/class/leds/lcd-backlight/brightness 例如 echo 255 > /sys/class/leds/lcd-backlight/brightness 代码修改亮度: Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS, brightness); //brightness 背光亮度 0~255 Settings.System.putInt(getContentResolver(),SCREEN_OFF_TIMEOUT, timeoutValues);//timeoutValues 灭屏时间 ms 判断是否在锁屏界面的函数 KeyguardManager: inKeyguardRestrictedInputMode(); 例: KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE); boolean keyguardexist = km.inKeyguardRestrictedInputMode(); OnTouchListener实现双击事件 class MyOnTouchListener implements View.OnTouchListener{ private long mLastTime = 0; private long mCurTime = 0; @Override public boolean onTouch(View v, MotionEvent event) { if(MotionEvent.ACTION_DOWN == event.getAction()){ mLastTime = mCurTime; mCurTime = System.currentTimeMillis(); if (mCurTime - mLastTime < 1000) { // 双击事件 关闭activity FullBlackActivity.this.finish(); return true; } } return false; } } 回到待机界面 Intent home = new Intent(Intent.ACTION_MAIN); home.addCategory(Intent.CATEGORY_HOME); this.startActivity(home); 定时器相关 采用Handler与线程的sleep(long)方法 Handler主要用来处理接受到的消息。 1. 定义一个Handler类,用于处理接受到的Message。 Handler handler = new Handler() { public void handleMessage(Message msg) { // 要做的事情 super.handleMessage(msg); } }; 新建一个实现Runnable接口的线程类,如下: public class MyThread implements Runnable { @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(10000);// 线程暂停10秒,单位毫秒 Message message = new Message(); message.what = 1; handler.sendMessage(message);// 发送消息 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 3. 在需要启动线程的地方加入下面语句: new Thread(new MyThread()).start(); 4. 启动线程后,线程每10s发送一次消息。 采用Handler的postDelayed(Runnable, long)方法 1. 定义一个Handler类 Handler handler=new Handler(); Runnable runnable=new Runnable() { @Override public void run() { // TODO Auto-generated method stub //要做的事情 handler.postDelayed(this, 2000); } }; 2. 启动计时器 handler.postDelayed(runnable, 2000);//每两秒执行一次runnable. 3. 停止计时器 handler.removeCallbacks(runnable); 采用Handler与timer及TimerTask结合的方法 1. 定义定时器、定时器任务及Handler句柄 private final Timer timer = new Timer(); private TimerTask task; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub // 要做的事情 super.handleMessage(msg); } }; 2. 初始化计时器任务 task = new TimerTask() { @Override public void run() { // TODO Auto-generated method stub Message message = new Message(); message.what = 1; handler.sendMessage(message); } }; 3. 启动定时器 timer.schedule(task, 2000, 2000); 简要说一下上面三步提到的一些内容: 1. 定时器任务(TimerTask)顾名思义,就是说当定时器到达指定的时间时要做的工作,这里是想Handler发送一个消息,由Handler类进行处理。 2. java.util.Timer.schedule(TimerTask task, long delay, long period):这个方法是说,delay/1000秒后执行task,然后进过period/1000秒再次执行task,这个用于循环任务,执行无数次,当然,你可以用timer.cancel();取消计时器的执行。 闹钟定时 AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(SEND_SMS_BEGIN), 0); am.set(AlarmManager.RTC_WAKEUP, 60*1000, pendingIntent); 耳机状态 private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state"; //保存状态文件位置 private boolean isHeadsetExists(){ //判断耳机是否插入的函数 FM源码 FMplayService.java char[] buffer = new char[1024]; int newState = 0; try { FileReader file = new FileReader(HEADSET_STATE_PATH); int len = file.read(buffer, 0, 1024); newState = Integer.valueOf((new String(buffer, 0, len)).trim()); } catch (FileNotFoundException e) { Log.e(LOGTAG, "This kernel does not have wired headset support"); } catch (Exception e) { Log.e(LOGTAG, "" , e); } return newState != 0; } 未插入耳机: # cat /sys/class/switch/h2w/state cat /sys/class/switch/h2w/state 0 插入耳机: # cat /sys/class/switch/h2w/state cat /sys/class/switch/h2w/state 1 sd卡和sim卡状态判断 //sdcard是否可读写 public boolean IsCanUseSdCard() { try { return Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); } catch (Exception e) { e.printStackTrace(); } return false; } //sim卡是否可读 public boolean isCanUseSim() { try { TelephonyManager mgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); return TelephonyManager.SIM_STATE_READY == mgr.getSimState(); } catch (Exception e) { e.printStackTrace(); } return false; } 开机启动,检查sim卡是否发生变更 (1)注册receiver,设置意图过滤器 <receiver android:name=".receiver.BootCompleteReceiver" > <intent-filter android:priority="1000" > <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> (2)接受开机广播,并判断sim卡时候发生更改 public class BootCompleteReceiver extends BroadcastReceiver { private static final String TAG = "BootCompleteReceiver"; private SharedPreferences sp; private TelephonyManager tm; @Override public void onReceive(Context context, Intent intent) { Log.i(TAG,"手机重启了"); sp = context.getSharedPreferences("config", Context.MODE_PRIVATE); boolean protecting = sp.getBoolean("protecting", false); //如果防盗保护开启 if(protecting){ //判断sim卡是否发生了变化 tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); String currentSim = tm.getSimSerialNumber(); String savedSim= sp.getString("sim", ""); if(savedSim.equals(currentSim)){ // sim卡为发生变化, do nothint }else{ //sim卡发生了变化 //发送报警短信 给安全号码 SmsManager smsManager = SmsManager.getDefault(); String destinationAddretss = sp.getString("safenumber", ""); smsManager.sendTextMessage(destinationAddretss, null, "sim change !!!", null, null); } } } } 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3886021.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

#WorkBuddy#/经验分享

# WorkBuddy 新手最常踩的 10 个坑与避坑指南 # 适用对象:刚接触 WorkBuddy 或用了不到一个月、总觉得"哪里不对"的用户。 核心结论:90% 的"不好用"不是工具不行,是用法没对上。本文汇总社区里被问最多的 10 个问题,每个都给出复现步骤、根因分析和解决方案——看完能少走至少一周弯路。配图说明:文中 5 张客户端截图均为按真实场景还原的模拟界面,文案与报错均来自实际使用反馈,可直接用于社区发布。 ## 目录 # 坑 1:AI 生成的表格/文档格式错乱坑 2:积分明明还有,突然提示"额度不足"坑 3:让 AI 读本地文件,结果它"看不见"坑 4:长任务执行到一半断了,白忙活坑 5:生成 PPT 后内容对不上需求坑 6:代码运行报错,AI 给的方案不生效坑 7:多轮对话后 AI"失忆",前面说的不算了坑 8:Connector 连不上,提示授权失败坑 9:输出内容太长被截断坑 10:同样的 Prompt,每次结果不一样一句话总结:避坑 checklist ## 坑 1:AI 生成的表格/文档格式错乱 # **症状**:让 AI 生成一个带格式的表格,复制到 Excel 或 Word 里列对不齐、中文乱码、字体全变。**根因**:Markdown 表格和标准办公软件的数据格式不是一回事。直接复制粘贴会丢失制表符、合并单元格等结构信息。**解决方案**:场景正确做法要进 Excel让 AI 输出 CSV 格式,或保存为 .xlsx 文件再下载要进 Word让 AI 直接生成 .docx 文件,不要复制 Markdown只是临时看用 WorkBuddy 自带的预览功能,不要导出**Prompt 模板**:"请将结果保存为 Excel 文件(.xlsx),列名用中文,日期格式统一为 yyyy-mm-dd,金额保留两位小数。" ## 坑 2:积分明明还有,突然提示"额度不足" ![](https://developer.qcloudimg.com/http-save/audit-12835205/068b68e5b26d2eb8ae1048dd4245bc07.png) # **症状**:账户显示剩余积分 3000+,执行一个中等任务却弹出"额度不足"。**根因**:WorkBuddy 的积分体系分"每日额度"和"账户积分"两档。每日额度是每天重置的免费调用上限;账户积分是额外攒的。大模型调用、复杂任务会优先扣每日额度,额度用完才扣账户积分。如果当日额度已耗尽,即使账户积分充足,部分任务也会被拦截。下图为该坑在 WorkBuddy 客户端中的真实表现(模拟截图,文案与报错均按真实场景还原):**解决方案**:先看清楚提示是"日额度"还是"账户积分"不足;日额度用完时,可手动切换消耗账户积分(部分场景支持);重度用户建议把高消耗任务集中到每日额度刷新后执行(通常凌晨重置)。 ## 坑 3:让 AI 读本地文件,结果它"看不见" ![](https://developer.qcloudimg.com/http-save/audit-12835205/d52719a3a517600e237cba29d854d48b.png) # **症状**:上传了一个 .xlsx 或 .pdf,AI 回复"未检测到文件"或分析的内容和文件对不上。**根因**:文件还在上传中,AI 已经开始处理;文件格式被系统识别为"不可读"(如加密 PDF、扫描版图片 PDF);文件太大,触发了大小限制。下图为该坑在 WorkBuddy 客户端中的真实表现(模拟截图,文案与报错均按真实场景还原):**解决方案**:情况处理方法上传没完成等文件显示"已上传"再发指令,不要急着回车加密/扫描 PDF先用 OCR 工具转成可编辑文本,再上传文件过大拆分成多个小文件,或只上传关键 Sheet/页格式不确定优先传 .xlsx、.csv、.txt,兼容性最好 ## 坑 4:长任务执行到一半断了,白忙活 # **症状**:让 AI 处理一个 5000 行的表格或写一份长报告,执行几分钟后报错中断,前面的结果也没保存。**根因**:单次对话有 Token/时间上限,超长任务容易触发截断;部分复杂操作(如多表合并、大量数据清洗)超出单次处理能力。**解决方案**:**分而治之**:把大任务拆成 3-5 个小步骤,逐步推进;**先采样后全量**:先让 AI 处理前 50 行验证逻辑,确认无误后再执行全量;**关键节点保存**:每完成一个子任务,让 AI 输出中间结果并保存为文件,不要全部堆在一轮对话里。**Prompt 模板**:"请先只处理前 50 行数据,展示处理逻辑和中间结果。我确认无误后,再执行全量处理。" ## 坑 5:生成 PPT 后内容对不上需求 # **症状**:让 AI 做一份 PPT,出来的框架很空、内容泛泛、数据全是占位符。**根因**:Prompt 里只说了"帮我做一份销售汇报 PPT",没有给素材、没有定结构、没有标重点。AI 没有读心术,信息越少,填空越多。下图为该坑在 WorkBuddy 客户端中的真实表现(模拟截图,文案与报错均按真实场景还原):**解决方案**:要素写法示例主题"Q3 销售复盘"页数"15 页左右"结构"封面→目标回顾→数据亮点→问题分析→下季度计划"数据源"数据见附件 Excel,重点看 Sheet2"风格"商务简洁,蓝白配色,每页不超过 6 行字"**Prompt 模板**:"基于附件 Q3 销售数据,生成一份 15 页的汇报 PPT。结构:封面→目标回顾→区域业绩对比(用柱状图)→Top3 成功经验→3 个主要问题→下季度重点计划。风格商务简洁,每页核心结论放在标题。" ![](https://developer.qcloudimg.com/http-save/audit-12835205/b298687e4d1d9708e71cf4a9620d1ce5.png) ## 坑 6:代码运行报错,AI 给的方案不生效 # **症状**:AI 写了一段 Python/Shell 代码,复制到本地运行报错;或者 AI 说"执行成功",但结果不对。**根因**:AI 不知道你的本地环境(Python 版本、包依赖、操作系统);路径、权限、编码等本地差异导致代码无法直接复用;AI 有时会"编造"不存在的 API 或参数。**解决方案**:**先给环境信息**:在 Prompt 里说明操作系统、Python/Node 版本;**小步验证**:让 AI 先写最小可运行片段,确认能跑通再扩展;**报错回传**:把完整的报错信息贴回对话,AI 修正准确率会大幅提升;**不要盲信**:涉及删除、修改系统文件的命令,先在沙箱或备份环境测试。 ## 坑 7:多轮对话后 AI"失忆",前面说的不算了 # **症状**:聊了 20 轮之后,AI 忘记了最初的任务目标,开始重复提问或偏离主题。**根因**:对话上下文有长度限制,超过一定轮数或 Token 数后,最早的内容会被"遗忘"。这是大模型架构的固有限制,不是 Bug。下图为该坑在 WorkBuddy 客户端中的真实表现(模拟截图,文案与报错均按真实场景还原):**解决方案**:策略做法定期小结每 5-8 轮让 AI 总结当前共识,作为后续对话的起点关键信息前置每轮对话把核心约束重复一遍(可以用引用格式)新开会话任务阶段切换时(如从"分析"到"输出"),果断新开一个对话,把前文摘要贴进去用文件传递把已确认的中间结果保存为文件,下一轮直接上传 ![](https://developer.qcloudimg.com/http-save/audit-12835205/9ebd175c87a5e3f1e16a764c811ba800.png) ## 坑 8:Connector 连不上,提示授权失败 # **症状**:点击某个 Connector(如腾讯文档、飞书、GitHub),弹出授权页面但授权后仍显示"未连接"。**根因**:授权窗口被浏览器拦截;授权 Token 过期或权限范围不足;企业版账号和个人版账号混用导致权限不匹配。**解决方案**:授权时确保浏览器弹窗未被拦截,允许打开新窗口;授权后返回 WorkBuddy 界面,手动刷新 Connector 列表;检查授权时选择的账号是否与 WorkBuddy 登录账号一致;企业版服务(如腾讯文档企业版)需管理员开通 API 权限,个人授权无效。 ## 坑 9:输出内容太长被截断 # **症状**:让 AI 输出一份完整报告,结果到一半突然结束,后面没了。**根因**:单次输出有 Token 上限,长内容会被截断。部分场景下 AI 也会"偷懒",用省略号代替详细展开。下图为该坑在 WorkBuddy 客户端中的真实表现(模拟截图,文案与报错均按真实场景还原):**解决方案**:**分段索取**:"先写第一部分:背景分析。写完后我提示你再写第二部分。"**扩写指令**:被截断后回复"继续"或"从上一段接着写",通常可以续上;**控制密度**:要求"只写要点,不要展开",减少单次输出量;**文件输出**:长内容让 AI 保存为文件下载,绕过聊天窗口的长度限制。 ## 坑 10:同样的 Prompt,每次结果不一样 # **症状**:同一个问题问两遍,答案不一样;甚至同一次复制粘贴,结果也有差异。**根因**:大模型本质上是概率生成,Temperature(随机性)不为 0 时,每次采样结果都会不同。这是设计特性,不是故障。**解决方案**:场景对策需要稳定结果在 Prompt 里加约束:"请严格按以下步骤执行,不要省略"需要可复现把确认好的结果保存为模板/文件,不要依赖重新生成结果差异大检查是否切换了模型版本(不同模型输出风格不同)追求一致性用"Step 1/2/3"结构化 Prompt,减少模型自由发挥空间 ## 一句话总结:避坑 checklist # 坑一句话解法格式错乱要文件直接生成文件,不要复制 Markdown额度不足分清"日额度"和"账户积分",大任务挑时段文件读不到等上传完成再指令,优先传 xlsx/csv长任务中断拆成小步,先采样验证PPT 太水给结构、给数据、给页数、给风格代码报错先报环境信息,小步验证,报错回传AI 失忆定期小结,关键信息前置,阶段切换开新会话Connector 失败查弹窗拦截、查账号一致、企业版需管理员开权限输出截断分段索取,长内容输出为文件结果不稳定结构化 Prompt,好结果及时固化 ---

优秀的个人博客,低调大师

使用WorkBuddy感受分享

先说最直观的感受:信息找人,不用人找信息。 以前做项目,最头疼的就是“找东西”。合同在哪?上次的审批流程走到哪了?这个客户之前是谁跟进的?翻聊天记录、翻邮件、翻文件夹,有时候光找这些就花掉半天时间。现在WorkBuddy把所有信息都串起来了,我只要在搜索框里敲几个关键词,相关项目、客户、单据、审批记录,清清楚楚列出来。更爽的是,它还会主动提醒我——该续签合同了、该催款了、某项任务快到期了,我一个做项目的人,再也不用靠脑子记这些琐碎的deadline,省心太多了。 协作效率的提升,是很明显的。 我们团队经常要跨部门沟通,以前发个需求,在微信群里@人,对方可能隔半天才回,或者干脆忘了。现在直接在WorkBuddy上建任务,指派责任人,设置截止时间,系统自动跟踪进度。谁完成了、谁超时了,一目了然,根本不用我去催。而且所有沟通记录都在任务下面,不会像微信那样被新消息刷走,翻历史记录特别方便。上周我们一个紧急项目,销售、技术、采购三个部门同时在线协作,以前至少要开两三次会才能对齐的事,这次在系统里一天就捋清楚了,大家都不用来回跑,效率直接翻倍。 管理层看数据,比以前靠谱多了。 以前老板问项目进度,我得先问各个负责人,再手动汇总,数据还经常对不上,有时候给老板的报表和实际差一大截,特别尴尬。现在WorkBuddy自动生成报表,所有数据都是实时更新的,从合同签约到回款周期,从项目进度到人员工效,一眼就能看明白。上个月我们复盘项目,发现某环节总是超时,系统自动分析出了瓶颈点,我们针对性地优化了流程,这个月的交付效率明显提高了。 几个小细节,挺打动我的。 一是手机端做得不错,出差在路上,用手机就能审批、看任务、回复消息,不用非得开电脑。二是系统很灵活,我们公司有些业务比较特殊,之前担心新系统不好用,结果跟实施顾问沟通后,很快就配置上了个性化模块,没有想象中那么僵化。 当然,也不是没有槽点。刚上线那两周,大家都不太习惯,老员工对操作流程不熟悉,内部培训花了不少时间。而且有些功能确实偏复杂,对于习惯简单操作的人来说,学习成本有点高。但熬过适应期之后,发现其实都是熟能生巧的事。 总的来说,用WorkBuddy最大的感受就是:省心、省力、省时间。 以前做项目,人围着流程转,天天追着人问进度;现在流程围着人转,系统帮我把杂事打理好,我只需要专注做好业务本身。如果你也在为公司管理混乱、效率低下发愁,真心建议试试这个工具,它可能不会让你立刻变强,但一定会让你少走很多弯路。 ![](https://developer.qcloudimg.com/http-save/audit-12668258/42da8d1e69263f924b195c8b4b831029.png) ![](https://developer.qcloudimg.com/http-save/audit-12668258/d329debf5c083b8280b006dcb848a8dd.png) ![](https://developer.qcloudimg.com/http-save/audit-12668258/e49e655de694d0bafe6d23e03d52f9a5.png) 「WorkBuddy」「AI办公」

优秀的个人博客,低调大师

技术分享连载(三)

内存管理 Q1:如图,在Editor中查看Profiler里的内存详细信息,发现Used Total中有个“Unity”,请问是什么意思?为什么会特别大? 在Editor中运行时,“Unity”大是正常的,因为在Editor中运行项目时,引擎包含了所有的资源占用的内存(除了部分纹理和Mesh是在GFX中),同时自身会进行很多的辅助操作来记录各种游戏运行信息。一般来说,在查看游戏运行时的真实消耗内存,我们均是推荐直接在发布游戏上通过Profiler进行查看,在Editor中运行游戏所看到的内存是要大很多的。 内存管理 Q2: 在进行内存优化时,Unity Profiler给出的数据和Android系统(adb dumpsys meminfo,已经考虑memtrack的影响 )的数据差距较大(已经分析了Profiler自身的内存占用),如何分析这部分差异,比如包括对显存消耗进行准确统计,OS消耗的统计等等? 内存差异较大是正常的,一般来说,Profiler统计的内存较为一致,而Android系统通过ADB反馈的PSS、Private Dirty等值则是差别很大。这主要是因为芯片和OS的不同而导致。具体的Android内存,建议直接查看Google Android OS的相关文档。 Unity Profiler反馈的则是引擎的真实物理使用内存,一般我们都建议通过Profiler来查看内存是否存在冗余、泄露等问题。 资源管理 Q3:iOS上PVRTC不支持NPOT的贴图压缩,在Android上可以用ETC2,但在iOS上不能压缩,内存消耗大。请问在iOS上有没有好的处理方案? ETC2仅能在支持OpenGL ES3.0的手机上进行使用,请研发团队在使用前谨慎考察支持ES3.0的手机在国内的覆盖范围。 PVRTC不支持NPOT的贴图压缩,这是Apple规定的,上层应用无权对此更改。我们仅能建议将纹理尽可能做成POT形式,否则只能接受内存较大的开销,没有其他更好的办法。 资源加载 Q4:怎样动态加载Navmesh? 目前Navmesh不支持动态加载,只能随场景一起加载, 因此可以考虑将带有Navmesh的场景打包成AssetBundle,然后使用LoadLevel加载AssetBundle中的场景。 Navmesh的动态加载已经在Unity的Roadmap中。而当前,Navmesh是和场景绑定的,也就是说目前只能通过LoadLevel(不支持LoadLevelAdditive的加载方式)来加载场景的同时,自动加载对应的Navmesh数据。替代方案是:将多个“场景Prefab”的Navmesh 合并到同一个场景中烘焙好(互不重叠),然后再将这些“场景Prefab”分离到各个单独的场景中去;在运行阶段,Navmesh随着第一个场景一次性加载,而对于其他的场景物件,再通过LoadLevelAdditive来加载对应的场景即可。缺点是为了使场景物件对齐Navmesh,在场景制作时就不能出现坐标上的重叠,因此仅供参考。 在Unity 5.x下,Lightmap的动态加载,需要通过脚本将烘焙时每个物件的Lightmapindex和Lightmapscaleoffset记录下,并在运行时动态加载后设置回去的方式来实现。因为目前Lightmapindex和Lightmapscaleoffset信息是和场景绑定在一起,储存在Lightmapsnap.assets 中,发布时也是放在场景信息中,因此不会记录在Prefab 上。 图形渲染 Q5:当关闭预渲染GI时会出现IndirectResolution,这个参数有什么用,为什么调大了以后会大大增加渲染时间,但是烘培出来却没有什么效果。 该值主要控制的是GI的烘焙密度,数值越大,表示每个单位距离内的Texel越多,即烘焙得越精致,自然烘焙的时间也越长。 该值并非越大越好,场景越小建议该值越低。该值为1时,对于多数场景,其烘焙效果已经足够了,升高该值,其效果也不会有明显提升。 原文出处:侑虎科技 转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

优秀的个人博客,低调大师

idea常用插件分享

本文主要推荐几款idea常用的插件,在日常开发中不仅可以装逼,还可以适当的提升开发效率。 注意:下载plugins失败或超时情况下,请勾选掉 settings --> Appearance&Behavior --> System Settings --> updates --> Use secure connection 1、activate-power-mode 根据Atom的插件activate-power-mode的效果移植到IDEA上 1.gif 2、Alibaba Java Coding Guidelines 阿里巴巴编码规约插件,极力推荐 2.gif 3、Background Image Plus idea背景修改插件,让你的idea与众不同,狂拽酷炫吊炸天。 4、Free Mybatis plugin mybatis 插件,让你的mybatis.xml像java代码一样编辑。 5、Grep console 自定义日志颜色 6、String Manipulation 强大的字符串转换工具。使用快捷键,Alt+m image.png Toggle style (camelCase, hyphen-lowercase, HYPHEN-UPPERCASE, snake_case, SCREAMING_SNAKE_CASE, dot.case, words lowercase, Words Capitalized, PascalCase) To SCREAMING_SNAKE_CASE (or to camelCase) To snake_case (or to camelCase) To dot.case (or to camelCase) To hyphen-case (or to camelCase) To hyphen-case (or to snake_case) To camelCase (or to words) To PascalCase (or to camelCase) Capitalize selected text 7、LomBok Plugin A plugin that adds first-class support for Project Lombok Features @Getter and @Setter @ToString @EqualsAndHashCode @AllArgsConstructor, @RequiredArgsConstructor eg: @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @NoArgsConstructor @Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog @Data @Builder (eg: User.builder.name("jackcooper").age(24).build(); ) @Singular @Delegate @Value @Accessors @Wither @SneakyThrows from Intellij 14.1 @val from Intellij 14.1 @var from Intellij 2016.2 @UtilityClass Lombok config system Code inspections Refactoring actions (lombok and delombok) 8、Key promoter 快捷键提示插件 9、CodeGlance 快速定位代码。右侧小地图。 697635-0450282604ad3e48.gif 10、Gsonformat 可根据json数据快速生成java实体类 697635-5a07f838223baaae.gif 11、Properties to YAML Converter Properties 转 YAML 格式插件 12、HighlightBracketPair image.png 13、findBugs 检查bug 14、MyBatis Log Plugin 显示mybatis的sql image.png image.png 15、restfultookit 16、Material Theme UI 强大的主题插件 image.png 17、GenerateAllSetter 一键生成一个对象的set方法并且赋予默认值 在对象字段多的时候非常方便 111.gif 18、VisualVM Launcher 运行java程序的时候启动visualvm,方便查看jvm的情况 比如堆内存大小的分配 某个对象占用了多大的内存,jvm调优必备工具 image.png 222.gif 19、Jrebel jreble最大的优点就是当你做任何项目中内容修改的时候只需要build一下,对应的资源直接加载到jvm中,不需要重启。 image.png 20、xrebel-微服务场景下性能问题排查神器 image.png 参考文章:https://juejin.im/entry/59fa8e5df265da43062a1aed

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册