SDK踩坑全纪录
No1:
Unity2017.1版本导出的android工程放到Android Studio上跑起来非常卡,Unity2017.3或4版本导出就没问题。
对比后发现gradle文件有差异,特此标注
1)gradle版本改为2.3.0
2)sdk版本改为27或以下
3)android块中加这句
aaptOptions {
noCompress '.unity3d', '.ress', '.resource', '.obb'
}
资源压缩的问题
No2:
Unity导出的android工程里暴露了唯一的Activity:UnityPlayerActivity,其实就是unity-class.jar包里的UnityPlayerActivity。
我们可以把暴露的Java类删除,继承unity-class.jar包里的UnityPlayerActivity,写一个新的类,这样的话,只要这个类实现了新的接口。Unity那边就可以通过反射调用相同的接口,从而实现了Android与Unity之间交互。
No3:
今天一天都在找权限问题,明明在清单文件里注册了权限,结果打成apk后,清单文件里权限就没了,找了整整一天的原因,结果是接的sdk里隐藏了这句
<uses-permission android:name="android.permission.READ_PHONE_STATE"
tools:node="remove"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:node="remove"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="remove" />
sdk是别人写的,让作者改吧
No4:
合并代码逻辑,每新建一个分支,提交代码后,都要合并到master主分支,原因是公共库给其他工程用的时候,不需要找最新的版本,只需要下载master分支就是最新的了。
No5:
打包提示:Error:java.lang.RuntimeException: Some file crunching failed, see logs for details
原因:
1.构建Gradle的时候,Gradle会去检查一下是否修改过文件的后缀名;
2.一般大多数是出现在图片上,.jpg修改成了.png就会出现这个问题;
3.9patch图片也可能出现这个问题。
解决方法:
gradle文件android块中增加
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
No5:
错误:uses-sdk:minSdkVersion 1 cannot be smaller than version 4 declared in library
原因:有类库没有配置最低兼容版本
解决:
defaultConfig {
minSdkVersion 10
targetSdkVersion 19
}
增加即可
No6:
aar里面是不能把其他aar打进去的,解决方法只有
1.多引用一次aar
2.把aar解压,分文件夹合成一个aar
No7:
library里如果compile了maven库,那么library打成aar是不会包含maven里的内容的,主工程引用library打成的aar时,需要再次compile maven库
No8:
报错:Duplicate files copied in APK META-INF/LICENSE
解决:android块中添加
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/ASL2.0'
}
No9:
运行apk提示
原因:主工程的jni文件下只有x86,armeabi_v7a两种架构,但是引入的aar或library里jni下除了x86,armeabi_v7a,还有其他的架构
解决:把多余的删除就好了
No10:
unity导出的android工程后,我们需要删除默认的UnityPlayerActivity启动页,然后再打成aar包,放到公共工程的lib中去,不然会有两个启动icon
No11:
maven仓库分四种类型:group仓库组、hosted本地仓库、proxy代理仓库、virtual虚拟仓库
本地上传的话,只能传到hosted仓库,所以gradle脚本只能写
http://127.0.0.1:8081/nexus/content/repositories/thirdparty
No12:
报错:Android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.message/com.example.message}; have you declared this activity in your AndroidManifest.xml?
原因:找不到activity,因为接入的sdk更新了,清单文件的配置改了
解决:重新接入最新版sdk
No13:
出包的时候,aar不要签名或者不要打release包,不然apk打出来有问题,亲测
No14:
apk游戏打不开,有可能是服务器端口权限没开放
No15:
EventBus是必须用单例的,所以在不同library中,最好通过导jar的方式使用自己的EventBus
No16:
unity的onBackPressed方法是无法监听到的,只有用监听物理按键的方式去抓,还有,因为activity是继承unityplayerActivity的,所以不要调super.onbackpressed方法!!!
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Log.d(TAG, "MainActivity--onBackPressed");
EventBus.getInstance().fireEvent(CommonEvents.MAIN_ACTIVITY_ON_BACK_PRESSED);
return true;
}
return super.onKeyDown(keyCode, event);
}
No17:
如何知道buildToolsVersion哪些版本是可用的?很简单,sdk下载后能看到
No18:
Unity的登录监听和android层的登录监听可能不是同时开启的,会导致登录失败,最好由unity调起android层的登录监听
No19:
涉及到google、facebook、twitter登录时,apk的包名要和申请时的包名一致,否则无法登录
No20:
facebook、twitter、google登录需要签名正确,facebook的签名是后验证的,过三天才会验证
No21:
library的compile不会达到生成的aar中,所以需要在主工程重新compile
No22:
使用google pay提示“无法购买您要买的商品“
1.保证VersionCode,上传的包和你测试的包一致
2.保证Payment List,google后台的单据名和你游戏中配置的一致
3.保证Payment Key,google后台key和你的key一致
4.保证Test User,你在测试阶段可以正常支付你的游戏
5.保证googlePlay商店,这个一般来说只要弹出支付是没问题的,但是如果商店无法使用,请检查vpn
6.保证Package Name,包名一致
7.上传到后台和测试的包签名要一致(不一致传不上去)
8.想要用其他谷歌账号测试游戏,需要让应用主账号发送给其他账号测试邀请连接,并让其他账号手动确认加入,才可以测试
9.有时候需要切换一下google后台的beta测试的发布和封闭模式,等十几分钟
No23:
公共模块
问题一:app_id与app_key错误
没有在经分后台配置app_id与app_key或者是填写的app_id与app_key对不上,所以app_id与app_key参数请以经分后台为准。
问题二:反馈回来的数据渠道有错
在配置文件中没有根据需要上的渠道来配置,在需要上的渠道配置对应上的渠道。
问题三:登录成功的回调没有执行到以及部分方法没有执行到问题
对接入的理解没有清晰的认识,公共模块组在对SDK进行封装供unity游戏对接的时候,以unity游戏主动调取接口为基准,公共封装作为一个Android SDK与unity游戏对接的桥梁,只需要对Android SDk中的接口做对应封装,不需要做过多的逻辑操作,不需要对Android SDK做主动调取,主动调取应该严格以unity游戏为主。
分享模块
问题四:分享调不起或者报ShareDialog为null问题
分享的初始化没有严格根据文档的要求接入,分享的初始化应该接入到需要分享的界面即Activity界面下的onCreate()生命周期方法里面,假如你不止一个界面需要分享功能,那么初始化就不止一次,应该在需要分享的界面都初始化;其次在接入具体分享(例如Google分享)的方法时,图片的路径不能为空,并且路径是手机本地图片的具体路径(请认真阅读接入文档,文档已经详细写出)。
支付模块
代码问题
问题五:点击登录时弹出“please check your google account”问题
这个问题,原因有二:
(1)接入googleSdk初始化接口没有严格按照文档放在指定位置。谷歌初始化需要放在登录成功的监听函数内。
(2)手机没有安装GooglePlay或者没有登录Google帐号。
-
google play商店 再打开一次授权就行了
非代码问题
问题六:谷歌支付弹出界面,出现“无法购买您要买的商品”问题
在谷歌控制台“https://play.google.com/apps/publish”中,请严格配置好以下信息:
(1)上传到谷歌控制台的Apk版本号、签名,和Android SDK的版本号、签名保持一致,并确定测试版本已经在谷歌控制台发布。
(2)谷歌控制台中配置需要购买的商品,且商品号与Android SDK调取的商品号严格保持一致。
(3)测试机上的谷歌帐号已添加到谷歌控制台中的测试人员列表中,并且在已登录该谷歌帐号的手机或者电脑中,点击邀请链接并加入测试人员。
- (4)手机中的第一次登录的谷歌帐号必须是邀请成功的测试帐号;或者手机中包含多个谷歌帐号,且弹出“无法购买您要买的商品”,请先删除其他不是测试帐号的谷歌帐号再进行测试。
问题七:谷歌支付弹出其他非正常支付窗口问题
只要接入GoogleSdk后能弹出窗口,代码都是没有问题的。但是弹出非正常支付接口的时候,应该要考虑相关的谷歌控制台配置和Android SDK配置是否严格按照文档配置。
以下为正常的配置:
(1)Android SDK的测试应用生成的APK已签名,并将发布版的APK上传到谷歌控制台。
(2)public key从谷歌控制台的“开发工具>权限与API”中获取。并放到应用的配置文件中。
(3)本地Android SDK的版本号、签名与上传到谷歌后台的APK的版本号、签名保持一致。
(4)在谷歌控制台添加测试人员帐号,并确保测试人员点击邀请链接加入。
(5)确保购买的商品号已经在谷歌控制台创建,并且生效,且分发地区确保已选择了测试所在地区。
No24:
调用googlePay支付无法弹出支付界面,提示如下:
GooglePayUtil Purchase fail : Null data in IAB result (response: -1002:Bad response received)
原因:google play的权限管理中
No25:
android studio的setting的file encoding都改成utf-8了,中文还是乱码
在build.gradle中加如下代码
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
No26:
下载jenkins.war包后,进入Jenkins.war包目录下,运行java -jar jenkins.war时报端口被占用的错误:java.net.BindException: Address already in use: bind
解决方法:修改Jenkins端口java -jar jenkins.war --httpPort=8081 8081不行就改8082
No27:
No28:
查看apk签名:
首先用解压软件解压出META-INF目录下的CERT.RSA文件
执行keytool -printcert -file D:\Desktop\CERT.RSA
或者直接keytool -printcert -jarfile apk路径
No29:
游戏登陆小米账号失败,返回错误码-102,界面提示《游戏服务》鉴权失败,无法登录。。。
解决方案:就算游戏没有内购的计费点,小米开放平台也必须随便配一个计费点,好坑啊!
No30:
编译提示:Could not find com.android.support:support-v4:26.0.2.
原因:support annotations自25.4.0之后support包不在sdk中更新了,需要用谷歌的maven库
解决方案:在主工程下添加
allprojects{
repositories{
maven{url "https://maven.google.com"}
maven{url "https://dl.google.com/dl/android/maven2"}
}
}
No30:
接入UC的sdk时候,需要从后台下载一张九游的图片,底部有gameid
这个gameid每个游戏都不一样,还不能直接用ps改,必须从uc后台下载
No31:
华为手机没有打印日志
1.在拨号界面输入“*#*#2846579#*#*”
2.依次进入“后台设置-->2.LOG设置-->LOG开关”,选择“LOG打开”
No32:
Windows命令查看文件MD5:
certutil -hashfile yourfilename.ext MD5
certutil -hashfile yourfilename.ext SHA1
certutil -hashfile yourfilename.ext SHA256
No33:
git分支名称对大小写是不敏感的,比如master主分支,你checkout Master也是可以切过去的,但是git pull会报错
No34:
Jenkins改名字的话,如果项目依赖了服务器上的资源,有可能导致打包失败,因为找不到以前的资源了
No35:
应用运行的时候如何报libxxx.so- text relocations的错误,原因是so库里的targetSdk版本低于build.gradle的targetsdk版本,把targetsdk版本改小(一般小于23)就可以了
No36:
小米渠道提审的时候提示签名和之前的不一致,而且提示每次提审的签名都不一样
原因,payment权限导致的
解决:清单文件删除 <uses-permission android:name="com.xiaomi.sdk.permission.PAYMENT" />
在MiCommplatform.Init之前增加MiCommplatform.setNeedCheckPayment(false);
No37:
如果compile远程地址,产生了jar包冲突。
其实这些远程依赖的jar包编译后是下载到了本地的,路径是C:\Users\Administrator\.gradle\caches\modules-2\files-2.1
然后对应去找冲突的jar包,复制出来,改成本地依赖,去掉冲突的.class文件即可
No38:
安装ubuntn后启动报错提示:此主机支持Intel VT-x,但Intel VT-x处于禁用状态
解决方案:重启电脑(不是虚拟机),按F2进入设置页,找到advanced->intel virtual technology,把disabled改为enabled
No39:
启动ubuntn时报错:The root filesystem on /dev/sda1 requires a manual fsck
解决方案:
硬盘sda1检测出现问题了,我用的解决办法是输入代码:fsck -c /dev/sda1
执行后一直按y,然后就成功了,再重启就好了
No40:
搜狗sdk1)手机号验证码登录 2)搜狗账号注册 3)电脑注册,app登录 这三种情况都提示ERROR_CODE:2001
原因:无效应用,参数错误
No41:
打包提示:Failed to execute aapt
原因:清单文件有些资源是不存在的,需要删掉
No42:
QQ接入sdk后使用qq账号登录,提示:该应用非官方正版应用,请去应用宝下载正版后进行qq登录(错误码100044)
原因:
1)如果游戏已上线,就是签名和线上签名不一致,还有可能是appid不对
2)如果游戏还没上线,是因为没上线的游戏属于测试环境下,要用调试的开发者qq账号才可以登录
No43:
打包提示:找不到apply plugin: 'com.android.library'或者apply plugin: 'com.android.application' 其实是gradle没引用
解决方案:在build.gradle里加入
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
No44:
打包提示:Failed to execute aapt
原因:有些资源找不到
No45:
打包报错:Can't process class [com/swiftfintech/pay/utils/Util.class] (Unknown verification type [9] in stack map frame))
原因:jar包冲突,删除即可
No46:
清单文件中多个替换是用逗号隔开
tools:replace="android:windowSoftInputMode,android:configChanges"
No47:
搜狗banner广告的关闭按钮是搜狗后台配置的,需要找搜狗的人打开
No48:
bycond对比工具失效解决办法
1)cmd运行命令whoami /user 得到SID
2)修改SID后运行reg delete "HKEY_USERS\<SID>\Software\Scooter Software\Beyond Compare 4" /v CacheId /f
No49:
打包提示清单文件冲突,出来一大坨,搜索error能确定具体的那个
No50:
有时候不在主工程,但是需要拿到资源id,通过以下方法
activity.getResources().getIdentifier(resName,"layout",activity.getPackageName())
如果是xml中的id,就这样写
activity.getResources().getIdentifier(resName,"id",activity.getPackageName())
就是说,本来R.XXX.资源名,XXX是什么,第二个参数就是什么
No51:
如果打包的时候报错找不到另一个module的资源,在build.gradle里增加
compile project(path: ':module的名字')
即可
No52:
倾斜的TextView和ImageView根本不需要自定view去实现,xml中自带属性
android:rotation="-5"
填写响应的角度就可以了
No53:
json解析如果存在两个相同的字段,值会被覆盖,小心
No54:
做开屏遇到一个问题,倒计时和跑马灯同时存在,倒计时会导致跑马灯每秒重新开始,出现一顿一顿的效果
解决方案是将跑马灯或者倒计时的宽度布局改为固定宽度
No55:
腾讯和广点通的sdk,腾讯登陆页要在开屏也之前才能扫码支付
No56:
引用本地aar,当A引用了一个aar,如果B依赖了A,那么B的build.gradle里也要加aar的路径
No57:
如果打包的时候报错找不到另一个module的资源,在build.gradle里增加
No58:
使用androidstudio打jar包:
在module的build.gradle中
task makeJar(type:Jar){
from('build/intermediates/packaged-classes/debug/') //从这个目录下取出默认jar包
into('build/') //将jar包输出到指定目录下
include('classes.jar')
rename('classes.jar', 'TestJar_V1.0.jar') //自定义jar包的名字
}
注意:gradle2.3的from路径是from('build/intermediates/bundles/release/'),gradle3.1的from路径是from('build/intermediates/packaged-classes/debug/')
makejar之前要先assembleDebug一下,生成aar,其实makejar就是把aar里的class.jar拿出来而已
No59:
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
中source.getConfig()有可能为null;
source.getConfig()要改为source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888
No60:
打包报错
If you are using the 'java' gradle plugin in a library submodule add
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
to that submodule's build.gradle file.
原因是导入的第三方jar包用的是JDK1.8编译的,而你本地的工程或者工程里的插件是用JDK1.7编译的
解决方案
android{
defaultConfig{
jackOptions{
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
jackOptions看你本地工程情况,可加可不加
No61:
在android开发的时候,有时候会遇到这样的问题
Error:Execution failed for task ':test:processDebugManifest'.> Manifest merger failed with multiple errors, see logs
但是要命的是,除了这个log,没有什么其他的有用信息了,怎么办?
处理方式是这样的:
首先进入命令行,输入命令
gradlew processDebugManifest --stacktrace
其中,processDebugManifest是log里面提到的,这个命令是会了获取更多的log信息。
No62:
unity出aar资源打包以后,app按电源键再打开会绕过锁屏。原因是打release和打debug包,dll文件会不一样,最好用release包来测
No63:
打包报错:与元素类型 “item” 相关联的 “name” 属性值不能包含 ‘<’ 字符
到sdk目录下找到/platform-tools/api/annotations.zip这个文件并解压。
用记事本打开以下两个文件,并且把标签内的 ‘<’ 和 ‘>’ 字符分别替换成 "<” 和 “>”。
android/accounts/annotations.xml
android/hardware/camera2/annotations.xml
android/hardware/camera2/params/annotations.xml
android/app/slice/annotations.xml
android/widget/annotations.xml
android/view/annotations.xml
android/view/textclassifier/annotations.xml
android/bluetooth/le/annotations.xml
android/media/annotations.xml
android/preference/annotations.xml
android/text/annotations.xml
保存并压缩,替换掉原来的annotatio
No64:
打包报错:Too many classes in --main-dex-list
顾名思义就是主dex里的class太多了,其实已经设置了multiDexEnabled为true,但还是无效,这时候就需要dex刀来显威力了
buildscript {
dependencies {
...
classpath 'com.ceabie.dextools:gradle-dexknife-plugin:1.5.9'
}
}
apply plugin: 'com.ceabie.dexnkife'
在build.gradle同级新增一个dexknife.txt文件
# 全局过滤, 如果没设置 -filter-suggest 并不会应用到 建议的maindexlist.
# 如果你想要某个包路径在maindex中,则使用 -keep 选项,即使他已经在分包的路径中.
-keep android.support.v4.view.**
# 这条配置可以指定这个包下类在第二dex中.
android.support.v?.**
# 使用.class后缀,代表单个类.
-keep android.support.v7.app.AppCompatDialogFragment.class
# 不包含Android gradle 插件自动生成的miandex列表.
-donot-use-suggest
-split **
# 将 全局过滤配置应用到 建议的maindexlist中, 但 -donot-use-suggest 要关闭.
#-filter-suggest
# 不进行dex分包, 直到 dex 的id数量超过 65536.
-auto-maindex
# dex 扩展参数, 例如 --set-max-idx-number=50000
# 如果出现 DexException: Too many classes in --main-dex-list, main dex capacity exceeded,则需要调大数值
-dex-param --set-max-idx-number=65536
# 显示miandex的日志.
-log-mainlist
# 如果你只想过滤 建议的maindexlist, 使用 -suggest-split 和 -suggest-keep.
# 如果同时启用 -filter-suggest, 全局过滤会合并到它们中.
-suggest-keep android.support.multidex.**
No65:
webview加载H5页面时,如果无法弹出对话框,增加如下设置即可
WebView.setWebChromeClient(new WebChromeClient());
即可
No66:
报错
Failed resolution of: Lorg/apache/http/params/BasicHttpParams;
原因是android 9.0限制了http,强制用https,第三方sdk也必须用https
解决方案在清单文件application中加入
<uses-library android:name="org.apache.http.legacy" android:required="false" />
即可
No67.
华为手机底部导航栏导致布局无法撑满整个屏幕,这时候就需要隐藏导航栏
//隐藏虚拟按键,并且全屏 protected void hideBottomUIMenu() { if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { View v = mActivity.getWindow().getDecorView(); v.setSystemUiVisibility(View.GONE); } else if (Build.VERSION.SDK_INT >= 19) { View decorView = mActivity.getWindow().getDecorView(); int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN; decorView.setSystemUiVisibility(uiOptions); } }
No68.
报错,原因是Android P 后谷歌限制了开发者调用非官方公开API 方法或接口
解决方案是在Application中调用
private void closeAndroidPDialog(){ try { Class aClass = Class.forName("android.content.pm.PackageParser$Package"); Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class); declaredConstructor.setAccessible(true); } catch (Exception e) { e.printStackTrace(); } try { Class cls = Class.forName("android.app.ActivityThread"); Method declaredMethod = cls.getDeclaredMethod("currentActivityThread"); declaredMethod.setAccessible(true); Object activityThread = declaredMethod.invoke(null); Field mHiddenApiWarningShown = cls.getDeclaredField("mHiddenApiWarningShown"); mHiddenApiWarningShown.setAccessible(true); mHiddenApiWarningShown.setBoolean(activityThread, true); } catch (Exception e) { e.printStackTrace(); } }
No69:
报错:java.lang.UnsatisfiedLinkError
解决:build.gradle里增加
ndk { abiFilter "armeabi-v7a" }
欢迎关注我的微信公众号:安卓圈