1.部分手机App唤起第三方支付(微信/支付宝)不成功
以支付宝为例,环境为华为Mate7 EMUI4.0(Android6.0)系统,体验发现代码流程正常,支付宝却未启动正常的支付界面,其他手机正常,想到Android6.0新的权限管理方案,于是查看权限管理发现支付宝的权限中 关联启动 一项未被授予,手动开启这项权限后正常。
本以为加上提示或者跳转告诉用户去开启支付宝的关联启动项就OK了,但是测试同学说美团App在同样的环境下不需要手动开启那项权限依然可以正常唤起支付宝宝,这TM就很尴尬了。最后通过查看支付宝官方最新集成文档并提问支付宝技术支持得到一个半肯定的回答,因为我们使用的支付宝SDK版本太老了,影响正常使用。项目中支付宝SDK中还是用的AliPay唤起的支付宝,这至少也是2年前的SDK版本了,不知道为什么一直没有更新,可能是抱着不出问题就不换的原则。通过demo测试确实和支付宝SDK版本有关, 经过替换最新版的支付宝SDK后验证一切正常。
2.H5交互相关
//java.lang.Throwable: A WebView method was called on thread ‘JavaBridge’. All WebView methods must be called on the same thread
1.与H5交互的交互中标注@JavascriptInterface的函数可被javaScript调用 但并不在Android主线程调用
所以此函数中不可进行UI操作或对WebView的操作
2.与H5交互的交互中标注@JavascriptInterface的函数命名为getUserId()与API冲突 在部分手机中出现权限报错(华为Mate10by8.0),不可用getUserId命名与H5交互的函数
3.//项目正式签名打包时报错mulit define错误
一般为依赖库重复引用冲突导致 以retrofit为例,retrofit会捆绑依赖okhttp
当其它lib中也有okhttp时会冲突(阿里云文件上传SDK需依赖okhttp),删掉lib中的okttp即可
可通过命令行查看app所有依赖库的lib树结构,具体命令百度
4//QQ分享成功后提示分享取消
1同时注意这里的APPid需要替换成你代码里配置的APPid
PlatformConfig.setQQZone(“100424468”, “c7394704798a158208a74ab60104f0ba”);
这两处的APPid应该是一致的,同时注意不要删掉tencent前缀!!!!
2注意实现onActivityresult方法
mShareAPI.onActivityResult(requestCode, resultCode, data);
5.//相机拍照机相册选择的开发相关
调用系统相机拍照获取图片分2种情况,如果启动相机时指定了Uri,则相机拍照结果会储存在该Uri下,并且onActivityResult中
的data返回为null 。如果启动相机时未指定Uri,则onActivityResult中data会返回照片缩略的Bitmap对象=data.getParcelableExtra(“data”)
6.RecyclerView常见问题解决方案,RecyclerView嵌套自动滚动,RecyclerView 高度设置wrap_content 无作用等问题。转自
1,ScrollView或者RecyclerView1 嵌套RecyclerView2 进入页面自动跳转到recyclerView2上面页面会自动滚动
貌似是RecyclerView 自动获得了焦点
两种解决办法
一,recyclerview去除焦点
recyclerview.setFocusableInTouchMode(false);
recyclerview.requestFocus();
二,在代码里面 让处于ScrollView或者RecyclerView1 顶端的某个控件获得焦点即可
比如顶部的一个textview
tv_goodsName.setFocusableInTouchMode(true);
tv_goodsName.requestFocus(); 2,RecyclerView 高度设置wrap_content 无作用,RecyclerView 高度适中铺满全屏的bug
解决方案:
这是RecyclerView兼容包的bug,23.2.0后官方已经修复了。
所以直接在gradle里设置用23.2.0及以上的RecyclerView:
compile ‘com.android.support:recyclerview-v7:23.2.0’
或者全部升级
api ‘com.android.support:appcompat-v7:25.3.0’
api ‘com.android.support:support-v13:25.3.0’
api ‘com.android.support:design:25.3.0’
3,RecyclerView 条目布局宽度设置match_parent无效果的问题解决
//这里为了解决recycleview不能撑满全屏的问题,这里layoutManager不管你布局里是否设置,都不准确,所以需要在代码里
//重新设置MATCH_PARENT
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()) {
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
};
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
xrecyclerview.setLayoutManager(layoutManager);
7.Can not perform this action after onSaveInstanceState异常处理
1.多数场景为在Activity中处理Fragment事务操作,如
FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
....
ft.commit(); //改为调用commitAllowingStateLoss()函数即可
2.少数场景为某些任务调用了当前Activity的finish()函数,当用户手动按下回退键执行onBackPress()时也会抛出这种异常,解决方法:
if (!isFinishing()) { //需要重写onBackPress()函数避免重复退栈操作
super.onBackPressed();
}
3.原因分析,因为activity在销毁前会调用onSaveInstanceState()保存数据。然查看源码FragmentManager中有一个checkStateLoss()函数如下,这个函数在Fragment退栈和commit()操作时都会被调用来检查状态,源码如下:
//BackStackState类中源码
public int commit() { //场景1中的ft.commit()调用实际最终由BackStackState的commit函数处理
return commitInternal(false);
}
public int commitAllowingStateLoss() {
return commitInternal(true);
}
int commitInternal(boolean allowStateLoss) { //最终都进到该函数中交由FragmentManager对象执行enqueueAction函数
....
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
//FragmentManager类中源码
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) { //可以看到普通的commit操作时allowStateLoss为false,才会执行checkStateLoss()函数,
//如果此时activity已经被销毁或者说onSaveInstanceState已经执行,那么在checkStateLoss()中就会抛出异常
checkStateLoss();
}
...
}
//FragmentManager类中源码checkStateLoss()
private void checkStateLoss() {
if (mStateSaved) { //mStateSaved在onSaveInstanceState之后会被置为true
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
...
}
场景2中原因类似,同样是因为onBackPress()函数中先执行FragmentManager的退栈操作popBackStackImmediate()函数,popBackStackImmediate()函数的第一步就是调用checkStateLoss()检查状态,可自行阅读。