一、三种常用的定时器 1.Handler类的postDelayed方法: final Handler mHandler = new Handler(); Runnable r = new Runnable() { @Override public void run() { //do something //每隔1s循环执行run方法 mHandler.postDelayed(this, 1000); } }; //主线程中调用: mHandler.postDelayed(r, 100);//延时100毫秒 2.用handler+timer+timeTask方法: final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { //do something } super.handleMessage(msg); } }; Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { Message message = new Message(); message.what = 1; handler.sendMessage(message); } }; //主线程中调用: timer.schedule(timerTask, 1000, 500);//延时1s,每隔500毫秒执行一次run方法 3.Thread+handler方法: final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { //do something } super.handleMessage(msg); } }; class MyThread extends Thread {//这里也可用Runnable接口实现 @Override public void run() { while (true) { try { Thread.sleep(1000);//每隔1s执行一次 Message msg = new Message(); msg.what = 1; handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } } } //主线程中调用: new Thread(new MyThread()).start(); 4.ScheduledThreadPoolExecutor方法: private ScheduledThreadPoolExecutor mThreadPoolExecutor; if (mThreadPoolExecutor != null) { mThreadPoolExecutor.shutdownNow(); } mThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); mThreadPoolExecutor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { } }, 0, 500, TimeUnit.MILLISECONDS); 二、三种延时的快捷方法: 1.Handler的postDelayed方法: new Handler().postDelayed(new Runnable() { @Override public void run() { //do something } }, 1000); //延时1s执行 2.timer + TimerTask方法: Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { //do something } },1000);//延时1s执行 3.Thread方法: new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000);//延时1s //do something } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); 自带定时器 CountDownTimer 利用 CountDownTimer 实现一个时长为 5 秒的 View 倒计时显示,要求从 5s 开始每隔 1 秒倒计时显示到 1s CountDownTimer countDownTimer = new CountDownTimer(totalTime, 2000) { @Override public void onTick(long millisUntilFinished) { updateFileData(fileId); //执行任务 } @Override public void onFinish() { if (User.getInstance().isLoginIng()) { if (countDownTimer != null) { countDownTimer.start(); } } } }; countDownTimer.start(); 三、定时轮询 为什么使用Service 普通的线程也可以达到在后台做事情的功能,那么为什么使用 Service呢?是因为 Service是系统的组件,它的优先级比普通的线程要高, 不容易被系统回收。而且 线程不好控制,Service相对好控制一些。运行在前台的Activity是不会被系统回收 的,而Service如果不想被 系统回收,就需要在Service中设置一下 startForeground(int,Notification) 具体的使用场景有: a、拥有长连接QQ b、定时轮询 c、服务里面注册广播接收者。有些广播接收者只能通过代码注册,比如屏幕锁屏、 屏幕解锁、电量发生变化等。 e、IntentService Android RxJava 实际应用讲解:(无条件)网络请求轮询 https://www.jianshu.com/p/11b3ec672812 四、沉浸式框架implementation 'com.hannesdorfmann.mosby3:mvp:3.0.0-alpha4' 五、获取结点元素 方式一: // 遍历root下的子节点有哪些 for (int i = 0; i < root.getChildCount(); i++) { AccessibilityNodeInfo child = root.getChild(i); Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); if ("dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) { Log.e("TIAOSHI###ViewPager", "----twoNode:" + child.getChildCount()); for (int y = 0; y < child.getChildCount(); y++) { AccessibilityNodeInfo child1 = child.getChild(y); Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); if ("android.widget.TabHost".equals(child1.getClassName())) { for (int j = 0; j < child1.getChildCount(); j++) { AccessibilityNodeInfo child2 = child1.getChild(j); Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText()); } } } } } 六、横向滑动 AblViewUtil.scrollHorizontal(10,600,100,600, new GestureCallBack() { @Override public void succ(GestureDescription gestureDescription) { } @Override public void fail(GestureDescription gestureDescription) { } }); 七、停止服务 AblStepHandler.getInstance().setStop(true); 八、定时器 private void daojishizreo(int a) { //启动计时器 //从0开始发射11个数字为:0-10依次输出,延时0s执行,每1s发射一次。 mdDisposable = Flowable.intervalRange(0, a + 1, 0, 1, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .doOnNext(new Consumer() { @Override public void accept(Long aLong) throws Exception { long b = a - aLong; } }) .doOnComplete(new Action() { @Override public void run() throws Exception { AblStepHandler.getInstance().setStop(true); Log.e("TIAOSHI###", "停止了"); } }) .subscribe(); } 九、for循环找控件 /** * 寻找留下你的精彩评论 */ private AccessibilityNodeInfo findcoment() { AccessibilityNodeInfo infooos=null; AccessibilityNodeInfo rootttt = AblService.getInstance().getRootInActiveWindow(); for (int j = 0; j < rootttt.getChildCount(); j++) { AccessibilityNodeInfo child = rootttt.getChild(j); Log.e("TIAOSHI###", "----1Node:" + child.getClassName() + ":" + child.getText()); if (!"dmt.viewpager.DmtViewPager$d".equals(child.getClassName())) { // Log.e("TIAOSHI###ViewPager", "----2Node:" + child.getChildCount()); for (int y = 0; y < child.getChildCount(); y++) { AccessibilityNodeInfo child1 = child.getChild(y); Log.e("TIAOSHI###", "----2Node:" + child1.getClassName() + ":" + child1.getText()); // if ("android.widget.LinearLayout".equals(child1.getClassName())) { for (int x = 0; x < child1.getChildCount(); x++) { AccessibilityNodeInfo child6 = child1.getChild(x); Log.e("TIAOSHI###", "----3Node:" + child6.getClassName() + ":" + child6.getText()); for (int z = 0; z < child6.getChildCount(); z++) { AccessibilityNodeInfo child7 = child6.getChild(z); // Log.e("TIAOSHI###", "----4Node:" + child7.getClassName() + ":" + child7.getText()); // if ("android.widget.LinearLayout".equals(child7.getClassName())) { for (int r = 0; r < child7.getChildCount(); r++) { AccessibilityNodeInfo child2 = child7.getChild(r); // Log.e("TIAOSHI###", "----5Node:" + child2.getClassName() + ":" + child2.getText()); for (int m = 0; m < child2.getChildCount(); m++) { AccessibilityNodeInfo child3 = child2.getChild(m); // Log.e("TIAOSHI###", "----6Node:" + child3.getClassName() + ":" + child3.getText()); for (int n = 0; n < child3.getChildCount(); n++) { AccessibilityNodeInfo child4 = child3.getChild(n); // Log.e("TIAOSHI###", "----7Node:" + child4.getClassName() + ":" + child4.getText()); for (int k = 0; k < child4.getChildCount(); k++) { AccessibilityNodeInfo child5 = child4.getChild(k); // Log.e("TIAOSHI###", "----8Node:" + child5.getClassName() + ":" + child5.getText()); for (int p = 0; p < child5.getChildCount(); p++) { AccessibilityNodeInfo child8 = child5.getChild(p); // Log.e("TIAOSHI###", "----9Node:" + child8.getClassName() + ":" + child8.getText()); } } } } } // } // } } } } // } } return infooos; } 十、超级大坑 目前无解 在做验证码登录的是时候,getRootInActiveWindow()方法的返回值为null,getWindow()方法也为null,网上查遍资料也没有 印象笔记搜索:getRootInActiveWindow()方法的返回值为null 解决办法是让,也没先返回home,然后再打开就可以了。 十一、导入手机联系人 遇到的两个问题:1是内容提供者的配置 2是权限的问题 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS); if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED){ requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS},REQUEST_CODE_ASK_PERMISSIONS); // return; } } 加入这段代码就好了。 十二、绑定服务 https://blog.csdn.net/imxiangzi/article/details/76039978?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control 十三、WindowManager.LayoutParams详解 https://blog.csdn.net/weixin_34055787/article/details/92576555 十四、在Android中用广播监听AccessibilityService的开启状态并更新UI界面https://blog.csdn.net/huang826336127/article/details/80139543 十五、Android RxJava/RxAndroid:takeWhile,直test测试条件通过才执行链式操作TestAblStep12 https://blog.csdn.net/zhangphil/article/details/79882700 十六、关机重启 AblStepHandler.getInstance().setStop(false); AblStepHandler.sendMsg(AblSteps.STEP_25); 十七、退出抖音 AblStepHandler.getInstance().setStop(false); AblStepHandler.sendMsg(AblSteps.STEP_192);//检测我的页面弹出了好友推荐对话框,并关闭 十八、捕捉弹框(获取事件) // TODO Auto-generated method stub // System.out.println("Enter->onAccessibilityEvent"); //判断是否是通知事件typeAnnouncement if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){ List text = event.getText(); if(text.size()>0) { CharSequence charSequence = text.get(0); String s = charSequence.toString(); Log.e("TIAOSHI", "有弹出"); Log.e("TIAOSHI", "有弹出==" + s); //获取消息来源 String sourcePackageName = (String) event.getPackageName(); //获取事件具体信息 Parcelable parcelable = event.getParcelableData(); //如果是下拉通知栏消息 if (parcelable instanceof Notification) { } else { //其它通知信息,包括Toast String toastMsg = (String) event.getText().get(0); Log.e("TIAOSHI", "有弹出" + toastMsg); Log.e("Latest Toast Message:", "" + toastMsg + " [Source: " + sourcePackageName + "]"); EventBus.getDefault().post(new SixEvent("success", toastMsg)); } } } private void getdouyin() { int num = 0; accessibilityNodeInfos = new ArrayList<>(); AccessibilityNodeInfo root = AblService.getInstance().getRootInActiveWindow(); for (int i = 0; i < root.getChildCount(); i++) { AccessibilityNodeInfo child = root.getChild(i); Log.e("TIAOSHI###", "----oneNode:" + child.getClassName() + ":" + child.getText() + ":" + child.getContentDescription()); // if ("androidx.viewpager.widget.ViewPager".equals(child.getClassName())) { for (int y = 0; y < child.getChildCount(); y++) { AccessibilityNodeInfo child1 = child.getChild(y); Log.e("TIAOSHI###", "----twoNode:" + child1.getClassName() + ":" + child1.getText() + ":" + child1.getContentDescription()); // if ("androidx.recyclerview.widget.RecyclerView".equals(child1.getClassName())) { for (int j = 0; j < child1.getChildCount(); j++) { AccessibilityNodeInfo child2 = child1.getChild(j); Log.e("TIAOSHI###", "----threeNode:" + child2.getClassName() + ":" + child2.getText() + ":" + child1.getContentDescription()); for (int x = 0; x < child2.getChildCount(); x++) { AccessibilityNodeInfo child3 = child2.getChild(x); Log.e("TIAOSHI###", "----fourNode:" + child3.getClassName() + ":" + child3.getText() + ":" + child1.getContentDescription()); for (int r = 0; r < child3.getChildCount(); r++) { AccessibilityNodeInfo child4 = child3.getChild(r); Log.e("TIAOSHI###", "----5Node:" + child4.getClassName() + ":" + child4.getText()+ ":" + child4.getContentDescription()); for (int m = 0; m < child4.getChildCount(); m++) { AccessibilityNodeInfo child5 = child4.getChild(m); Log.e("TIAOSHI###", "----6Node:" + child5.getClassName() + ":" + child5.getText()+ ":" + child5.getContentDescription()); for (int p = 0; p < child5.getChildCount();p++) { AccessibilityNodeInfo child6 = child5.getChild(p); Log.e("TIAOSHI###", "----7Node:" + child6.getClassName() + ":" + child6.getText()+ ":" + child6.getContentDescription()); for (int t = 0; t < child6.getChildCount();t++) { AccessibilityNodeInfo child7 = child6.getChild(t); Log.e("TIAOSHI###", "----8Node:" + child7.getClassName() + ":" + child7.getText()+ ":" + child7.getContentDescription()); } } } } } } } // } // } } } Rect rect = new Rect(); child7.getBoundsInScreen(rect); Log.e("TIAOSHI###", "----8Node:" + "(" + rect.left + "," + rect.top + ")" + "," + "(" + rect.right + "," + rect.bottom + ")"); 数据更新进度条:http://www.zyiz.net/tech/detail-56306.html 抢红包的demo: http://www.voidcn.com/article/p-cujkxxnt-bpb.html