把代码和Apk分享给大家,各取所需,挂机的直接Apk,编程的程序员直接源代码
https://pan.baidu.com/s/1rXSVZAf2dVfYKiwoLFhSEg 提取码:nbiw
能写到现在确实不容易,文章被各个平台各种封杀。越是干货越是难以存活,什么运营抖音、头条、企鹅、百家。各位清醒一下吧,你知道那有多难吗?我在抖音上看到一个疯子发个视频说:每天写1000篇软文发布到各个平台上,这样月入十万。你当我们是AI机器人啊。我在知乎上看到个骂人的,不过他骂得对,天天喊着抖音运营、带货500万粉丝,出教程….怎么可能啊如果每天赚几千几万谁还发文章啊。在知乎上发如何搞抖音全过程都不封号我发个薅羊毛给我一顿封杀啊。其实我也不知道这个能不能发出去,权且当最后一篇吧,不再搞了,研究技术可以,文章我就不再发AutoJs的了。有Python爱好者和Ai爱好者也可以关注我,以后的时间会专注Python方向的东西。如:
跑题了,还是把这个最后一篇搞定吧!
分3个方向介绍吧,一个是软件业务功能,另一个是配置,在一个是核心技术,
第一、业务介绍
近90个日夜的奋斗还有一个成果物,就是薅羊毛个人版。个人版是把我认为合理的都列上了,可以循环反复的执行代码,中间也可以自动签到。也可以手动签到。业务功能不敢写,一写就封杀给大家截图吧!
第二、系统配置
小视频和小说的我放到一起了。大概有30个。其实老铁根本用不了那么多,一天就24个小时弄前10个高收益的就可以了。另外我强调的是咱不能学白云大妈,可一个养薅那样会被发现的。一般薅2个小时基本可以,在参数里设置150-200下滑动就可以了。
另外App是支持排序的,排序条件是先修改数字在点就checkbox。这样系统就会按照数字索引排序了。
再有就是App支持签到,一键签到和自动签到。建议不开启自动签到,如果app你没安装容易卡死,目前我还没解决。
最后就是App支持刷了多久,在页面上可以清晰的看到,我现在用的是百进制所以有2小时99分的概念。
另外屏幕滑动时间是根据你当前网速来配置的,如果是wifi那么8s就可以了,如果流量搞没了就15秒因为你是3G了,速度慢没加载出来。
控制台建议不要开启,有一些事件是点击屏幕,容易被控制台给遮挡。
自动签到最好是设置在清晨6点,有的时候会莫名其妙的卡住,或者干脆就不开启,手动签到。
程序关闭时间,如果是个人玩就把设置早晨,让手机休息一下吧。
是否关闭App,华为手机可以开,因为我三个手机都是华为的,别的手机就别开了,调用的是屏幕点击强制关闭App,目的是减少内存浪费提高手机利用率。但是不同的手机点击强制关闭不一样,小米最奇葩,没做那么多兼容,所以大家不是华为就别开这个功能了。
叫个人版是有原因的,给大家解惑一下。AutoJs是基于Android的无障碍服务,而且这个全自动辅助是基于Android7.0以上版本的。 问题来了,这个无障碍服务极其不稳定,莫名其妙被关闭是家常便饭,尤其是我的华为Mate10(别见笑手机烂了点).我发现一个小秘密哈哈,价值几何你们自己考虑,Android7.0一直亮屏并运行AutoJs无障碍服务就没被关闭过。在这样的模式下想来个集群真的很难。
如果有工作室想搞那还是ROOT版本吧,免R的还不稳定。当然R的也是有问题的你们都懂…
写在最后我在App中将90个日夜的提炼的app已经放到前9。大家可以查看图到底错过没有。还有就是自动刷刷刷的软件就是个娱乐,娱乐娱乐不要指望薅羊毛发家致富也切莫可一只羊薅,咱不能学白云大妈。
第三、核心技术
本身AutoJs已经把无障碍核心都封装好了,我们只是在上面应用。我再一次强调使用的是Autojs4.1.0版本。虽然有BUG但是也基本完成了核心任务,替作者点个赞。我写的这个App有这么一个痛点,就是3000多行代码居然在一个页面上,我试验了好多回AutoJs4.1.0做项目的时候打包运行报错,所以没有办法只能单文件,而且不能调试,全靠记忆力和逻辑。截个图给兄弟们看看。
窗体加载就是系统初始化的内容,比如构建菜单、UI等操作。
窗体事件就是各类按钮的事件和绑定列表的事件。
业务代码就是各个App的操作,如果是有特别的就特殊处理,没有就执行公共方法。
公共函数,这个要重点说一下,其实整个代码整个我认为最重要,他可以无限的复用到其他UI航区,另外ui.layout也是非常非常非常重要的。公共函数代码分享给大家:
/**
*点击一下屏幕
*/
function clickScreen() {
var x = device.width -device.width*0.2;
var y = device.height-device.height*0.2 ;
toastLog("点击屏幕" + x + ":" + y);
let clickResult= click(x, y);
toastLog("单击屏幕返回值:"+clickResult);
}
/**
* 屏幕向下滑动并延迟8至12秒
*/
function slideScreenDown(startX, startY, endX, endY, pressTime) {
swipe(startX, startY, endX, endY, pressTime);
let delayTime = random(8000, 12000);
sleep(delayTime);//模仿人类随机时间
}
/**
* 薅羊毛App悬浮框
*/
function woolFloaty() {
var window = floaty.rawWindow(
);
window.setPosition(device.width, device.height / 2)
setInterval(() => { }, 1000);
//记录按键被按下时的触摸坐标
let x = 0;
let y = 0;
//记录按键被按下时的悬浮窗位置
let windowX;
let windowY;
//移动窗口
//按下时长超过此值则执行长按等动作
let downTime = 500;
//记录定时执行器的返回id
let Timeout = 0;
window.setSize(100, 100);
window.main.setOnTouchListener(
function (view, event) {
switch (event.getAction()) {
case event.ACTION_DOWN:
x = event.getRawX();
y = event.getRawY();
windowX = window.getX();
windowY = window.getY();
//创建一个定时器用来定时执行长按操作。
Timeout = setTimeout(() => {
toast("薅羊毛线程已经被关闭!");
threads.shutDownAll();
Timeout = 0;
}, downTime);
return true
case event.ACTION_MOVE:
//移动距离过大则判断为移动状态
if (Math.abs(event.getRawY() - y) > 5 && Math.abs(event.getRawX() - x) > 5) {
//移动状态清除定时器
if (Timeout) {
//定时器存在则清除定时器。
clearTimeout(Timeout);
Timeout = 0;
};
//移动手指时调整悬浮窗位置
window.setPosition(windowX + (event.getRawX() - x), windowY + (event.getRawY() - y));
};
return true;
case event.ACTION_UP:
if (Timeout) {
//清除定时器。
clearTimeout(Timeout);
Timeout = 0;
//执行点击事件。
toast("点击");
};
return true;
}
return true
}
)
}
/**
* 屏幕向下滑动并延迟8至12秒
*/
function slideScreenDown(startX, startY, endX, endY, pressTime, timesInterval) {
swipe(startX, startY, endX, endY, pressTime);
let randomMin = timesInterval * 1000;
let randomMax = (parseInt(timesInterval) + 2) * 1000;
let delayTime = random(randomMin, randomMax);
sleep(delayTime);
}
/**
* 输出Tosat和Info日志
* @param {日志消息} messagge
*/
function toastInfo(message) {
toast(message);
console.info(getTime()+""+message);
}
/**
* 输出Tosat和Error日志
* @param {日志消息} messagge
*/
function toastError(message) {
toast(message);
console.error(getTime()+""+message);
}
function toastLog(message){
toast(message);
console.log(getTime()+""+message);
}
function toastWarn(message){
toast(message);
console.warn(getTime()+""+message);
}
/**
* 链接的数组并返回新数组
* @param {原始数组}} compositeArray
* @param {被链接的数组} concatArray
*/
function concatArray(compositeArray, concatArray) {
for (var element in concatArray) {
if (typeof (concatArray[element]) == "function") {
continue;
}
compositeArray.push(concatArray[element]);
}
return compositeArray;
}
/**
* 获取当前时间格式yyyyMMdd
*/
function getDate() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
if (month < 10) {
month = "0" + month;
};
var day = date.getDate();
if (day < 10) {
day = "0" + day;
};
return year + "-" + month + "-" + day;
}
/**
* 获取当前时间格式yyyyMMddHHMMSS
*/
function getTime() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
if (month < 10) {
month = "0" + month;
};
var day = date.getDate();
if (day < 10) {
day = "0" + day;
};
var hour = date.getHours();
if (hour < 10) {
hour = "0" + hour;
};
var minute = date.getMinutes();
if (minute < 10) {
minute = "0" + minute;
};
var sec = date.getSeconds();//得到秒
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + sec;
}
/**
* 强制停止app
* @param {应用名称} appName
*/
function stopApp(appName) {
try {
openAppSetting(getPackageName(appName));
sleep(3000);
if (className("android.widget.Button").text("强行停止").exists()) {
className("android.widget.Button").text("强行停止").findOnce().click();
}
sleep(3000);
if (className("android.widget.Button").text("确定").exists()) {
className("android.widget.Button").text("确定").findOnce().click();
toastLog(appName + "已经停止!");
}
else {
let closeButton = className("android.widget.Button").text("强行停止").find();
closeButton[0].click();
toastLog(appName + "已经停止!");
}
} catch (e) {
toastLog(e);
}
}
/**
* JS构建Map
*/
function Map() {
var obj = {};
this.put = function (key, value) {
obj[key] = value;//把键值绑定到obj对象上
}
//size方法,获取Map容器的个数
this.size = function () {
var count = 0;
for (var attr in obj) {
count++;
}
return count;
}
//get方法,根据key获取value的值
this.get = function (key) {
if (obj[key] || obj[key] === 0 || obj[key] === false) {
return obj[key]
} else {
return null;
}
}
//remove方法,删除方法
this.remove = function (key) {
if (obj[key] || obj[key] === 0 || obj[key] === false) {
delete obj[key]
}
}
//each方法,遍历方法
this.eachMap = function (callBack) {
for (var attr in obj) {
callBack(attr, obj[attr])
}
}
}
function bSort(arr) {
var len = arr.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两对比,元素交换,大的元素交换到后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
/**
* map排序(核心是冒泡有点笨)
*/
function mapSort(mapTask) {
// threads.start(function () {
// console.show();
// });
var arr = [];
var result = [];
mapTask.eachMap(function (key, value) {
arr.push(parseInt(value));
result.push(key);
});
var len = arr.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两对比,元素交换,大的元素交换到后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
//value交换key也得换
var keyTemp = result[j + 1];
result[j + 1] = result[j];
result[j] = keyTemp;
}
}
}
//toastInfo(arr);
//toastInfo(result);
return result;//返回数组
// for (var i = 0; i < len; i++) {
// for (var j = 0; j < len - i - 1; j++) {
// toastInfo(arr[j]);
// toastInfo(arr[j + 1]);
// toastInfo(arr[j] > arr[j + 1]);
// if (arr[j] > arr[j + 1]) {
// //相邻元素进行对比
// var valueTemp = arr[j + 1];//交换元素
// arr[j + 1] = arr[j];
// arr[j] = valueTemp;
// //value交换key也得换
// var keyTemp = result[j + 1];
// result[j + 1] = result[j];
// result[j] = keyTemp;
// }
// }
// }
}
AutoJs4.1.0系列教程到这里就结束了。欢迎大家转载、评论、关注。
另外个人开通付费咨询和付费开发基于AutoJs的插件,私信就可以,谢谢
最后把代码和Apk分享给大家,各取所需,挂机的直接Apk,编程的程序员直接源代码:https://pan.baidu.com/s/1rXSVZAf2dVfYKiwoLFhSEg 提取码:nbiw