中国大学MOOC Android 客户端开发提效之页面信息

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a5/a528383c8708e024bd346de7cb55db3d.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要描述了怎么样提高一个客户端开发排查和定位的效率,并且动手写了一个小工具的实践和思考,以及团队中其他合作者能够提高了定位问题效率,验证功能是否准确的效率。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"作者","attrs":{}},{"type":"text","text":"/马杰 中国大学 MOCC 团队","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"编辑","attrs":{}},{"type":"text","text":"/刘振宇","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"一、前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"中国大学 MOOC 是由网易与高教社携手推出的在线教育平台,承接教育部国家精品开放课程任务,向大众提供中国知名高校的 MOOC 课程。目前,无论是课程数量、质量还是社会影响力,中国大学 MOOC 都已成为全球领先的中文慕课平台。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在日常的 Android 开发中,我们经常会遇到以下的一些问题:测试、运营、产品同学跑过来说这个页面出了问题,赶紧看下。这时候客户端开发同学就需要赶紧定位到具体的某个页面。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"据观察,大部分的情况下对于一个突发页面的问题定位,或者业务方想让开发者确认这个页面的业务逻辑的时候,客户端开发者,往往需要花费比较长的时间去给业务方答复。如果近期业务可能还能记得,但是客户端的页面比较多,想要快速定位到具体业务页面,那么就需要花更多的时间去找相关的页面。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以本文的想法是怎么","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"快速的找到对应的页面","attrs":{}},{"type":"text","text":",帮助开发","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"快速的进入业务代码","attrs":{}},{"type":"text","text":",快速的回复业务方提出的问题。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"二、方案实施","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在探讨方案的时候,我们需要对比目前有哪些方案,对比之后再选择一种更加有效的方法。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.1 解决问题的常用方式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 Android 开发中解决上述提供的问题,常用的有以下 3 种方式:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"打开 Android studio,靠着源码记忆,文案记忆去搜索;","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 adb 命令来过滤当前的 activity;","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"// windows\nadb shell dumpsys window windows | Select-String -Pattern 'mCurrentFocus|mFocusedApp|mLastOpeningApp|mObscuringWindow'\n \n// Mac\nadb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mLastOpeningApp'","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"全局搜索关键文案。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面 3 种方式是能够解决问题,但从","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"时间效率","attrs":{}},{"type":"text","text":"上分析,可以估算一下每一种方式大概需要多长时间:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第一种","attrs":{}},{"type":"text","text":",按照个人经验,熟悉项目代码的同学最快也要几十秒左右,慢的话 10 几分钟;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第二种","attrs":{}},{"type":"text","text":",使用 adb 能够几秒就定位到页面,但是需要记住命令,或者提前设置命令快捷方式;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第三种","attrs":{}},{"type":"text","text":",如果有很多相同文案,需要多搜索几遍,时间也可能是10几秒到1分钟不等。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有上面几种方式得出的时间效率就是几秒到几分钟不等,而且基本都是需要代码或者 adb 的开发工具,依赖于开发环境。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然需要花的时间也不少,那么是不是应该做一个工具来提升更快的定位速度,提升定位效率呢?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.2 更加高效的方法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实思路很简单,就是写一个开发的SDK,用来实时关注当前的页面信息。这个页面信息主要包含如下的信息:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"当前 Activity 是哪个?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"当前的 Fragment 是哪个?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"当前页面的参数传递,如:intent 中的各种参数是什么?","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"效果图如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7a3b85ab3e7e23bc4f10cd674b9e88f7.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从上面信息就能够很快的定位到当前的页面,当一个页面的深度到非常深的时候,这样的小工具就特别好用:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"最快速度只要几秒","attrs":{}},{"type":"text","text":"就能快速定位到页面,效率提升","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"快几十倍不止","attrs":{}},{"type":"text","text":"。而且能够当着测试和产品的面,能够把当前关键的参数给他看,如:xxxId、 埋点信息等。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.3 主要实现原理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的小工具,主要的工作是","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"获得当前的Activity","attrs":{}},{"type":"text","text":"。获得当前Activity的方式主要有以下几种方式:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"通过 RunningTaskInfo的 topActivity。该方法在后续的一些版本已经被禁用;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"手写代码管理Activity。这个方法比较粗暴,维护比较麻烦;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"通过反射 ActivityThread获得 currentActivityThread 从 mActivities 中查询获得;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"使用AccessibilityService 这个辅助功能,这个方法获得信息比较少;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"通过 ActivityLifecycleCallback 监听来获得。","attrs":{}}]}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"经过对比,选择使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"AccessibilityService","attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ActivityLifecycleCallback","attrs":{}},{"type":"text","text":" 这2种方式去尝试。以下就简单的说下这2种方法的实现,并进行二者之间的对比以及最后做出的选择。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.1 ActivityLifecycleCallback 方式","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"private static Activity topActivity;\n @Override\npublic void onActivityResumed(Activity activity) {\n topActivity = activity;\n}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是不是很简单?为了避免内存泄漏,可以在 onDestroy 的时候把 topActivity 设置成 null。这种方式","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"简单快速","attrs":{}},{"type":"text","text":",不需要申请权限。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.2 AccessibilityService 方式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"继承 AccessibilityService","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"@Override\n public void onAccessibilityEvent(AccessibilityEvent event) {\n Log.d(TAG, \"onAccessibilityEvent\");\n if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {\n if (event.getPackageName() != null && event.getClassName() != null) {\n ComponentName componentName = new ComponentName(\n event.getPackageName().toString(),\n event.getClassName().toString()\n );\n ActivityInfo activityInfo = tryGetActivity(componentName);\n boolean isActivity = activityInfo != null;\n if (isActivity) {\n Log.d(TAG, \"CurentActivity \" + componentName.flattenToShortString());\n Log.d(TAG, \"CurentActivity \" + event.getPackageName().toString());\n }\n }\n }\n }\nprivate ActivityInfo tryGetActivity(ComponentName componentName) {\n try {\n return getPackageManager().getActivityInfo(componentName, 0);\n } catch (PackageManager.NameNotFoundException e) {\n return null;\n }\n }","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"manifest 配置","attrs":{}}]}]}],"attrs":{}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"\n \n \n \n \n ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"需要 res/xm/accessibilityservice.xml 文件","attrs":{}}]}]}],"attrs":{}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和 ActivityLifecycleCallback 相比,这种方式相对复杂点,但是也还是简单的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.3 2种方式的对比","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"实现角度","attrs":{}},{"type":"text","text":"对比,使用 ActivityLifecycleCallback 比 AccessibilityService 更加简单。但是 AccessibilityService 有个优势就是可以不用集成到自己的 app 里面,可以独立运行,可以查看所有的当前页面是属于哪个 Activity,可以跨进程使用。使用 ActivityLifecycleCallback 必须要集成到自己的 app 中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"实践过程","attrs":{}},{"type":"text","text":"中,其实我们不只是想获得当前的 Activity ,我们还想知道当前的 Activity 中有哪些当前的 fragment,当前的 Activity 从上一个 Activity 中获得了哪些参数,当前的fragment 中有哪些参数等细节信息,那么只能集成到 app 中去的时候才会比较容易获得,所以最后选择了使用 ActivityLifecycleCallback 的方式。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.4 页面更详细的信息","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般页面上的信息开发,简单一点的就是一个 Activity 然后简单布局,复杂一点的基本都是 Activity + (ViewPager)Adatper + fragment,有时候 fragment 里面还会有 ViewPager 装载着 fragment, 对于不熟悉代码的人找对应的业务逻辑页面和代码,还是需要花费不少时间的。所以页面信息 fragment 也很重要。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"\ntopActivity.getIntent().getExtras();// 获得 activity 的页面参数\ntopActivity.getSupportFragmentManager().getFragments(); // 获得 activity 一级中的 fragments\nfragment.getChildFragmentManager().getFragments();// 对应 fragment 中的 fragments\nfragment.getArguments() // 获得 fragment的页面参数","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"三、 提高效率举例","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个页面信息采集,这里列举了几个使用场景,来证明效率得到了提高:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"对于","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}},{"type":"strong","attrs":{}}],"text":"客户端开发者","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":",能够快速的定位到当前出错的页面,特别是刚来的开发,或者不熟悉这块业务的,或者业务页面深度比较深的时候;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}},{"type":"strong","attrs":{}}],"text":"页面核心参数的确认","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"。比如详情页面需要一些 id","attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"这些详细参数就不需要客户端同事打断点的方式去获取,运营和测试自己可以去查看;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"在","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}},{"type":"strong","attrs":{}}],"text":"精品课和云课堂集成","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"的时候,能够让测试同学快速的区分哪个是精品课里面的页面,哪个是云课堂里面的页面,这样方便测试知道当前页面是属于哪个业务端的;(这个场景是网易内部融合项目)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}},{"type":"strong","attrs":{}}],"text":"页面全链路参数传递验证场景","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"。比如:首页点击需要传递转化率的参数一直传递到下单页面,平时都是开发自己验证,有这个工具后,产品也能在提测后,从测试包上自己查看验证。","attrs":{}}]}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"四、 页面信息其他想法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"关于页面信息场景增强,以下几种页面信息方式,是认为可以进行扩充的:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"可以获得 RecyclerView 中的 adapter;(有很多布局逻辑,放到了 adapter 里面的 ViewHolder)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"webview 当前信息的监控;(前端同事调试)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"网络看板的监控;(当前页面的网络请求信息)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"不连接电脑 Logcat 日志查看看板;(不用连接电脑,获得 adb 信息)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"参考线,界面元素位置,对应元素的颜色。(UI 走查的验证)","attrs":{}}]}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上的几点,主要是按照自身 app 的情况去判断是否需要实现,判断哪些实现性价比比较高。目前已经实现的,基本都是个人认为","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"性价比是比较高","attrs":{}},{"type":"text","text":"的东西。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"五、 总结","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当我们遇见一个问题的时候,首先思考这个问题是不是自己比较难受的点,然后观察其他人是否有类似的情况。这个问题常用的解决方案什么?有没有工具方法去替代?如果没有,可以不可以用比较低的成本去制造一个工具,最后来提升自己的效率,这个工具如果能够帮助其他人,那么能效就更加好了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"-END-","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章