Files
fuzhu/doc/技术文档
renjianbo 73f866ca5b commit
2026-01-06 10:32:14 +08:00

395 lines
19 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
一、三种常用的定时器
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<Long>() {
@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/RxAndroidtakeWhile直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<CharSequence> 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