今天下了个Android Studio,准备换个平台,但是创建新的项目遇到点问题,网上也没有找到完整的解决方法,研究了一下发出来供大家参考 问题:找不到R文件 报错Error:Execution failed for task ':app:processDebugResources'. > com.android.ide.common.process.ProcessException: Failed to execute aapt 问题原因:compileSdkVersion高于buildToolsVersion,可以用高版本的build-tool去构建一个低版本的sdk工程,但是反过来就不行了 解决方法:1.更新Android-SDK Build-Tools 2.修改build.gradle中相应版本号 之后我的问题就解决了 可能对于很多人来说根本不是问题,但是既然我遇上了,也就有可能有朋友还会遇到相同问题,希望能提供参考 from:https://www.cnblogs.com/madzxr/p/6322504.html
View Details// 定义 const ApiBridge = { msgQueue: [], callbackCache: [], callbackId: 0, processingMsg: false, isReady: false, isNotifyReady: false }; ApiBridge.callNative = function(clz, method, args, callback) { var msgJson = {}; msgJson.clz = clz; msgJson.method = method; if (args != undefined) msgJson.args = args; return prompt(JSON.stringify(msgJson)); }; // 调用 setTimeout(() => { this.$ApiBridge.callNative("KCApiTSLModule", "notifyF", { action: 'closePage', param: {} }); }); 以上代码经测试不能很好的兼容ios,下面的代码可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
; (function(window) { if (window.WebViewJSBridge) return; window.WebViewJSBridge = {}; console.log("--- kerkee init begin---"); var browser = { versions: function() { var u = navigator.userAgent, app = navigator.appVersion; return { trident: u.indexOf('Trident') > -1, //IE presto: u.indexOf('Presto') > -1, //opera webKit: u.indexOf('AppleWebKit') > -1, //apple&google kernel gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //firfox mobile: !!u.match(/AppleWebKit.*Mobile.*/), //is Mobile ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //is ios android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android iPhone: u.indexOf('iPhone') > -1, //iPhone or QQHD iPad: u.indexOf('iPad') > -1, //iPad iPod: u.indexOf('iPod') > -1, //iPod webApp: u.indexOf('Safari') == -1, //is webapp,no header and footer weixin: u.indexOf('MicroMessenger') > -1, //is wechat qq: u.match(/\sQQ/i) == " qq", //is qq, wxwork: u.indexOf('wxwork') > -1 //is wechat }; }(), language: (navigator.browserLanguage || navigator.language).toLowerCase() } var global = this || window; var ApiBridge = { msgQueue: [], callbackCache: [], callbackId: 0, processingMsg: false, isReady: false, isNotifyReady: false }; ApiBridge.create = function() { ApiBridge.bridgeIframe = document.createElement("iframe"); ApiBridge.bridgeIframe.style.display = 'none'; document.documentElement.appendChild(ApiBridge.bridgeIframe); }; ApiBridge.prepareProcessingMessages = function() { ApiBridge.processingMsg = true; }; ApiBridge.fetchMessages = function() { if (ApiBridge.msgQueue.length > 0) { var messages = JSON.stringify(ApiBridge.msgQueue); ApiBridge.msgQueue.length = 0; return messages; } ApiBridge.processingMsg = false; return ''; }; ApiBridge.callNative = function(clz, method, args, callback) { var msgJson = {}; msgJson.clz = clz; msgJson.method = method; if (args != undefined) msgJson.args = args; if (callback) { var callbackId = ApiBridge.getCallbackId(); ApiBridge.callbackCache[callbackId] = callback; if (msgJson.args) { msgJson.args.callbackId = callbackId.toString(); } else { msgJson.args = { "callbackId": callbackId.toString() }; } } if (browser.versions.wxwork || browser.versions.weixin) { return; } if (browser.versions.ios) { if (ApiBridge.bridgeIframe == undefined) { ApiBridge.create(); } // var msgJson = {"clz": clz, "method": method, "args": args}; ApiBridge.msgQueue.push(msgJson); if (!ApiBridge.processingMsg) ApiBridge.bridgeIframe.src = "kcnative://go"; } else if (browser.versions.android) { // android return prompt(JSON.stringify(msgJson)); } }; ApiBridge.showVersion = function() { return browser.versions; } ApiBridge.log = function(msg) { ApiBridge.callNative("ApiBridge", "JSLog", { "msg": msg }); } ApiBridge.getCallbackId = function() { return ApiBridge.callbackId++; } ApiBridge.onCallback = function(callbackId, obj) { if (ApiBridge.callbackCache[callbackId]) { ApiBridge.callbackCache[callbackId](obj); } } ApiBridge.onBridgeInitComplete = function(callback) { ApiBridge.callNative("ApiBridge", "onBridgeInitComplete", {}, callback); } ApiBridge.onNativeInitComplete = function(callback) { ApiBridge.isReady = true; if (callback) { callback(); ApiBridge.isNotifyReady = true; } } ApiBridge.compile = function(aIdentity, aJS) { var value; var error; try { value = eval(aJS); } catch (e) { var err = {}; err.name = e.name; err.message = e.message; err.number = e.number & 0xFFFF; error = err; } ApiBridge.callNative("ApiBridge", "compile", { "identity": aIdentity, "returnValue": value, "error": error }); } var _Configs = { isOpenJSLog: false, isOpenNativeXHR: false }; var kerkee = {}; /***************************************** * 事件监听 *****************************************/ kerkee.Event = {}; // kerkee.Event.LOADED = "loaded"; // kerkee.Event.LOAD_ERROR = "load_error"; // kerkee.Event.LOAD_PROGRESS = "load_progress"; kerkee.addEventListener = function(event, callback) { ApiBridge.callNative("event", "addEventListener", { "event": event }, callback); } /* Scroll to the bottom of the page when the callback function and the threshold setting */ //callback:Return to the page in webview upper vertex Y value kerkee.registerHitPageBottomListener = function(callback, threshold) { ApiBridge.callNative("ApiBridge", "setHitPageBottomThreshold", { "threshold": threshold }); kerkee.onHitPageBottom = callback; }; kerkee.registerScrollListener = function(callback) { ApiBridge.callNative("ApiBridge", "setPageScroll", { "isScrollOn": true }); kerkee.onPageScroll = callback; }; kerkee.notifyF = function(aString) { ApiBridge.callNative("KCApiTSLModule", "notifyF", aString); }; global.KCApiTSLModule = kerkee; /***************************************** * 接口 *****************************************/ kerkee.testJSBrige = function(aString) { ApiBridge.callNative("jsBridgeClient", "testJSBrige", { "info": aString }); }; kerkee.openJSLog = function() { _Configs.isOpenJSLog = true; } kerkee.closeJSLog = function() { _Configs.isOpenJSLog = false; } kerkee.commonApi = function(aString, callback) { ApiBridge.callNative("jsBridgeClient", "commonApi", { "info": aString }, callback); } kerkee.onDeviceReady = function(handler) { ApiBridge.onDeviceReady = handler; if (ApiBridge.isReady && !ApiBridge.isNotifyReady && handler) { handler(); ApiBridge.isNotifyReady = true; } }; kerkee.invoke = function(clz, method, args, callback) { if (callback) { ApiBridge.callNative(clz, method, args, callback); } else { ApiBridge.callNative(clz, method, args); } }; kerkee.onSetImage = function(srcSuffix, desUri) { var obj = document.querySelectorAll('img[src$="' + srcSuffix + '"]'); for (var i = 0; i < obj.length; ++i) { obj[i].src = desUri; } }; /* * var windowOpen = function (url) { ApiBridge.callNative("JavascriptAPIInterceptor", "windowOpen", { "url" : url }); }; */ global.ApiBridge = ApiBridge; global.kerkee = kerkee; global.jsBridgeClient = kerkee; kerkee.register = function(_window) { _window.ApiBridge = window.ApiBridge; _window.kerkee = window.kerkee; _window.console.log = window.console.log; _window.open = window.open; }; ApiBridge.onBridgeInitComplete(function(aConfigs) { if (aConfigs) { if (aConfigs.hasOwnProperty('isOpenJSLog')) { _Configs.isOpenJSLog = aConfigs.isOpenJSLog; } if (aConfigs.hasOwnProperty('isOpenNativeXHR')) { _Configs.isOpenNativeXHR = aConfigs.isOpenNativeXHR; } } if (_Configs.isOpenJSLog) { //global.console.log = ApiBridge.log; } ApiBridge.onNativeInitComplete(ApiBridge.onDeviceReady); }); })(window); |
View Details
Android编译出错:The Android Gradle plugin supports only Kotlin Gradle plugin version 1.2.51 and higher. Project ‘Test’ is using version 1.2.30. 打开build.gradle(Project) 修改buildscript中的ext.kotlin_version = ‘1.2.30’ 改成ext.kotlin_version = ‘1.2.51’ 最后点击Sync Now,重新编译就好了 from:https://blog.csdn.net/qq_34947048/article/details/85250198
View Details今天安装了Android Studio 3.2,打开一个旧工程,编译提示"No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android" 网上也有解决办法,就是下载旧版的NDK,将其中的toolchain复制到新版的NDK中 但是感觉这种方式,不是解决的正道。 经过对新版NDK的研究,发现NDK的更新记录里有一段话 This version of the NDK is incompatible with the Android Gradle plugin version 3.0 or older. If you see an error like No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android, update your project file to [use plugin version 3.1 or newer]. You will also need to upgrade to Android Studio 3.1 or newer. 也就是说新版本的NDK与3.0及以前旧版的Android Gradle plugin插件不兼容 其实解决方法很简单,就是修改build.gradle中的红字部分,改为3.1以上版本即可
1 2 3 4 5 6 |
dependencies { classpath 'com.android.tools.build:gradle:3.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } |
from:https://blog.csdn.net/vocanicy/article/details/83004626
View Details编译错误提示:Gradle sync failed: Could not run build action using Gradle distribution 'https://services.gradle.org/distributions/gradle-4.1-all.zip'. 点击Gradle Console NDK is missing a "platforms" directory. If you are using NDK, verify the ndk.dir is set to a valid NDK directory. It is currently set to D:\AndroidStudioSDK\ndk-bundle. If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning. 不言而喻,NDK缺少一个“platforms”目录。如果您正在使用NDK,请验证NDK。将dir设置为有效的NDK目录。目前它被设置为D: AndroidStudioSDK\ndk-bundle。如果不使用NDK,请从ANDROID_NDK_HOME或local中卸载NDK变量。属性删除此警告。 这个错误Google 的坑。目前只有兼容最新的NDK版本才能解决。 解决办法: 1.打开SDK Manager 2.勾选上NDK最新版本,安装成功后Apply 3.安装完成后重新build下项目搞定! from:https://blog.csdn.net/github_36787585/article/details/82841129
View Details修改系统变量 变量名:ANDROID_SDK_HOME 变量值:存放avd的路径,如:D:\AVD 在Android Studio中运行模拟器时,提示Error: Not enough disk space to run AVD '….'. Exiting。是说安装模拟的磁盘空间不足,导致无法运行模拟器。 Android Studio 安装之后,默认的模拟器会安装在C盘中,可以打开模拟器管理界面,右键查看(Show on disk)模拟器安装的目录。如下图: 我的模拟器安装路径为: C:\Users\Administrator\.android\avd, 其中的avd文件夹就是用来存放模拟器镜像文件的。 第一步:需要将Pixel_API_27.avd的文件夹移出C盘,放入空间足够的磁盘中。 第二步:就是要修改Pixel_API_27.ini(在此就称为模拟器配置文件吧,我也是新手不太懂)文件中模拟器的路径。 然后重新运行模拟器,没有问题应该可以运行起来。 from:https://www.cnblogs.com/wang2804355025/p/13155556.html
View Details面试之家只是为了学习和交流使用Weex,题库等内容不可用于商业项目 在Weex开发中,使用自定义Module的方式,来扩展Weex的能力,官方教程在这里,这里我以自定义分享模块来举例 第一步 先创建一个继承与NSObject的基类UM_WeexModule,然后引入头文件#import <WeexSDK.h>,并继承WXModuleProtocol协议。 第二步 实现方法并暴露给JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
- (void)shareEvent:(NSDictionary *)parames callback:(WXModuleKeepAliveCallback)callback { if (![parames isKindOfClass:NSClassFromString(@"NSDictionary")]) { [SVProgressHUD showErrorWithStatus:@"非法传参"]; return; } [UMSocialUIManager showShareMenuViewInWindowWithPlatformSelectionBlock:^(UMSocialPlatformType platformType, NSDictionary *userInfo) { switch (platformType) { case UMSocialPlatformType_Sina: { if (![[UMSocialManager defaultManager]isInstall:UMSocialPlatformType_Sina]) { [SVProgressHUD showErrorWithStatus:@"未安装新浪客户端"]; return ; } } break; case UMSocialPlatformType_WechatSession: { if (![[UMSocialManager defaultManager]isInstall:UMSocialPlatformType_WechatSession]) { [SVProgressHUD showErrorWithStatus:@"未安装微信客户端"]; return ; } } break; case UMSocialPlatformType_WechatTimeLine: { if (![[UMSocialManager defaultManager]isInstall:UMSocialPlatformType_WechatTimeLine]) { [SVProgressHUD showErrorWithStatus:@"未安装微信客户端"]; return ; } } break; case UMSocialPlatformType_QQ: { if (![[UMSocialManager defaultManager]isInstall:UMSocialPlatformType_QQ]) { [SVProgressHUD showErrorWithStatus:@"未安装QQ客户端"]; return ; } } break; case UMSocialPlatformType_Qzone: { if (![[UMSocialManager defaultManager]isInstall:UMSocialPlatformType_Qzone]) { [SVProgressHUD showErrorWithStatus:@"未安装QQ客户端"]; return ; } } break; default: break; } NSString *type = parames[@"type"]; NSString *title = parames[@"title"]; NSString *des =parames[@"des"]; NSString *picUrl = parames[@"picUrl"]; NSString *linkUrl = parames[@"linkUrl"]; //创建分享消息对象 UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; if ([type isEqualToString:@"link"]) { //创建网页内容对象 UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:title descr:des thumImage:picUrl]; //设置网页地址 shareObject.webpageUrl = linkUrl; //分享消息对象设置分享内容对象 messageObject.shareObject = shareObject; } else if ([type isEqualToString:@"pic"]) { //创建图片内容对象 UMShareImageObject *shareObject = [[UMShareImageObject alloc] init]; [shareObject setShareImage:picUrl]; //分享消息对象设置分享内容对象 messageObject.shareObject = shareObject; } else if ([type isEqualToString:@"richText"]) { //设置文本 messageObject.text = title; //创建图片内容对象 UMShareImageObject *shareObject = [[UMShareImageObject alloc] init]; //如果有缩略图,则设置缩略图 shareObject.thumbImage = [UIImage imageNamed:@"icon"]; [shareObject setShareImage:picUrl]; //分享消息对象设置分享内容对象 messageObject.shareObject = shareObject; } [[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:nil completion:^(id data, NSError *error) { if (error) { callback(error.userInfo[@"message"],false); }else{ [SVProgressHUD showSuccessWithStatus:@"分享成功"]; callback(@"1",false); } }]; }]; } - (void)setalias:(NSDictionary *)params { [UMessage addAlias:[NSString stringWithFormat:@"%@",params[@"userID"]] type:params[@"type"] response:^(id _Nonnull responseObject, NSError * _Nonnull error) { }]; } |
第三步 将方法抛出给JS
1 2 |
WX_EXPORT_METHOD(@selector(shareEvent: callback:)) WX_EXPORT_METHOD(@selector(setalias:)) |
第四步 初始化时注册到WeexSDK
1 |
[WXSDKEngine registerModule:@"UM_Event" withClass:NSClassFromString(@"UM_WeexModule")]; |
第五步 JS调用
1 2 3 4 5 6 7 8 |
var um_share = weex.requireModule('UM_Event'); um_share.shareEvent({ type:'pic', title:'title', picUrl:'https://mianshizhijia.oss-cn-hangzhou.aliyuncs.com/resourse_image/%E5%88%86%E4%BA%AB.jpg', }, callback => { }); |
结语 本篇文章旨在分享如何通过自定义Module来扩展Weex的能力,由于最近在忙于找工作,所以写的不是很深入,等过段时间稳定之后,会在继续分享Weex实现原理,以及从注册方法到可以被JS调用中间的实现过程。 作者:GL_fire 链接:https://www.jianshu.com/p/37b884515125 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
View Details上一篇文章我们配置了jdk version,这一节就来配置Android SDK环境搭建 Android SDK是Android平台上进行软件开发所需要的开发包,这里我们通过安装Android Studio的方式来安装Android SDK,Android Studio 是Android开发的IDE(集成开发环境),至少是2.0 或者更新版本 同样打开如下连接,此官方网站容易被墙 https://developer.android.com/studio/index.html 如果打不开换下面的路径,此为 android sdk 中文网站,下载 Android Studio http://www.androiddevtools.cn/ 然后运行你们下载的Android Studio进行安装,全选,然后下一步 到此处后,路径可以修改,我就都安装在D盘了,而且还是在同一个目录下,建议大家按照我的来安装, 注意安装目录不能有中文 第一个安装目录修改为 D:\Android\AndroidStudio 第二个安装目录修改为 D:\Android\sdk 我的安装位置 然后一直下一步,去掉勾选,点击finish 然后打开刚才修改的安装路径 D:\Android\sdk,运行 SDK Manager.exe 勾选下面几个(23.0.2一定要下),然后点击 install packages 安装成功后就开始安装环境变量,同样是在用户环境变量中新建一个(因为我已配置好) 变量名: ANDROID_HOME 变量值: D:\Android\sdk 然后在修改用户环境变量 path,是添加两个 变量名: path 变量值: %ANDROID_HOME%\platform-tools %ANDROID_HOME%\tools 如果环境变量是如下图的小伙伴,则在变量值最后面加上 ;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools 同样最后我们来检测是否安装和配置好,输入cmd打开命令行工具 输入 adb 如果出现的结果跟下面的图一样,那么恭喜你环境已经搭建好了 weex的环境变量就这样配置成功了,那么就开始入坑之旅吧! from:https://blog.csdn.net/k491022087/article/details/72934862
View Details1.配合使用调用app原生的方法(h5页面不需要回调和数据) 实例1
1 2 3 4 5 6 7 8 9 |
// 通知客户端,token失效 callTokenLostToApp(){ let boswer = vm.config.getBrowser() if(boswer == 'isiOS'){ window.webkit.messageHandlers.tokenExpiredTransmit.postMessage(1); }else if(boswer == 'isAndroid'){ window.tokenExpiredTransmit.jsMethod(1) } }, |
实例2
1 2 3 4 5 6 7 8 9 |
// 关闭页面 closePageApp(cb){ let boswer = vm.config.getBrowser() // IOS 关闭页面 if(boswer == 'isiOS'){ // 这段代码是固定的,必须要放到js中 window.webkit.messageHandlers.closePage.postMessage(1); // 安卓关闭页面 }else if(boswer == 'isAndroid'){ window.closePage.jsMethod(1) } }, |
2.配合使用调用app原生的方法(h5页面需要回调和数据) // 从App获取UUID(手机唯一标识)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// 从App获取UUID(手机唯一标识) getSystemInfoFromApp(cb){ let boswer = vm.config.getBrowser() // IOS 获取UUID if(boswer == 'isiOS'){ // 这段代码是固定的,必须要放到js中 function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } /*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/ setupWebViewJavascriptBridge(function(bridge) { /*JS给ObjC提供公开的API,ObjC端通过注册,就可以在JS端调用此API时,得到回调。ObjC端可以在处理完成后,反馈给JS,这样写就是在载入页面完成时就先调用*/ bridge.callHandler('getSystemInfoFromApp', function(responseData) { if(cb && typeof cb == 'function'){ cb(responseData) }else{ return responseData } }) }) // 安卓获取UUID }else if(boswer == 'isAndroid'){ let systemInfo = window.AndroidWebView.getSystemInfoFromApp(); if(cb && typeof cb == 'function'){ cb(systemInfo) }else{ return systemInfo } } }, |
标红字段为调用的app端定义的方法名,需要app端定义方法配合 from:https://www.cnblogs.com/wendyAndJken/p/9318501.html
View Details打开AS时出现了Unsupported Modules Detected: Compilation is not supported for following modules: app, KeyboardView. Unfortunately you can’t have non-Gradle Java modules and Android-Gradle modules in one project的错误,解决步骤如下: (1)关闭as (2)删除.idea目录 (3)删除app/build目录 (4)重新打开as from:https://blog.csdn.net/qq_40600379/article/details/106485687
View Details