记录开发当中遇到的问题及小知识点
发布时间:2021-09-03 14:44 浏览次数:次
一、You cannot start a load for a destroyed activity
这应该是基本上每一个人最开始都会遇到的错误了!原因是当你的acitivity已经销毁了但是异步任务还在进行,若此时你在异步任务当中用到了Glide那么就会直接闪退
解决方法网上也有非常多,感觉都挺不错的但是不建议使用getApplicationContext传给with(),虽然很方便但是分分钟内存泄漏!目前是这样解决(具体哪种好以后再做深入的研究)
private boolean isAttached;
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
isAttached = true;
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
isAttached = false;
}
public void glideImage(String url, int errorResId, ImageView imageView) {
if (isAttached) {
Glide.with(this)
.load(url)
.dontAnimate()
.placeholder(errorResId)
.error(errorResId)
.into(imageView);
}
}
二、You must not call setTag() on a view Glide is targeting
手动给Glide into的ImageView设置tag或者在复用contentview时item的根部局就是ImageView时就会报这个错!查看源码就能知道原因是与其内部维护的tag冲突了我是直接setTag( key,Object)解决
@Override
public Request getRequest() {
Object tag = getTag();
Request request = null;
if (tag != null) {
if (tag instanceof Request) {
request = (Request) tag;
} else {
throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
}
}
return request;
}
三、Glide暂停加载,启动加载
列表滚动的时候暂停加载
Glide.with(mContext).pauseRequests();
列表未滚动时开始加载
Glide.with(mContext).resumeRequests();
四、 Glide加载高度wrap_content时保证图片不变形
在网上查了许多解决办法但是都不太适合自己,使用override会导致加载速度变慢,很蛋疼
我的解决方案是自定义ImageView重写onMeasure方法并在xml设置这两个属性
android:adjustViewBounds=“true”//保持原图长宽比
android:scaleType=“fitXY”//充满宽高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
//高度根据使得图片的宽度充满屏幕计算而得
int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
安卓各版本适配
一、Android6.0动态权限
引入RxPermission
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.5'
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar'
1
2
3
单权限
RxPermissions rxPermission = new RxPermissions(MeetingDetailActivity.this);
rxPermission.request(Manifest.permission.CAMERA)
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if (aBoolean) {//同意权限
}
}
});
多权限(不理会用户拒绝、不再询问的方式,接受的是一个可变参数)
private void requestRxPermissions(String... permissions) {
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(@NonNull Boolean granted) throws Exception {
if (granted){//已获取权限
}else {//拒绝了任意一个权限
}
}
});
}
1
多权限(需要处理用户拒绝、不再询问的方式,permission.name可以拿到权限名)
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.requestEach(permissions)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(@NonNull Permission permission) throws Exception {
if (permission.granted) {
} else if (permission.shouldShowRequestPermissionRationale){//拒绝权限请求
} else {
// 拒绝权限请求,并不再询问
// 可以提醒用户进入设置界面去设置权限
}
}
});
二、Android7.0共享文件(无法对外暴露file类型的URI)
1.在清单文件中声明一个Provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="任意命名,之后获取URI要用到"
android:exported="是否需要对外开放(true/false)"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
2.在res目录下新建xml文件夹,创建一个filepaths.xml(与Provider的resource对应)
该xml文件可以指定各种路径,具体就不细说了,直接百度安卓7.0共享文件一堆堆
<?xml version="1.0" encoding="utf-8"?>
<resource>
<paths>
<external-path
name="external"
path="" />
</paths>
</resource>
3.打开系统相机拍照(记住要申请CAMERA以及WRITE_EXTERNAL_STORAGE权限)
当初刚遇到这个问题的时候耽误了很长时间,provider、xml换了一个又一个但死活拿不到照片,后来才猛然想起没有申请WRITE_EXTERNAL_STORAGE
private Uri imageUri;
private void openCamera() {
takePicFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//分版本获取URI
//通过FileProvider创建一个content类型的Uri
imageUri = FileProvider.getUriForFile(BuyProjectActivity.this, "这里对应清单文件Provider的authorities", takePicFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //表示临时授权该Uri所代表的文件
} else {
imageUri = Uri.fromFile(takePicFile);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
startActivityForResult(intent, Constant.RequestCode.TAKEPHOTO_REQUESTCODE);
}
三、Android8.0填坑记录
通知栏适配
startService进行try catch处理
允许安装未知来源应用
透明主题的Activity不允许设置方向
桌面图片适配
全面取消隐式广播
应用内更新的相应适配
二维码扫描
关于二维码扫描这块可是花了够多心思,在github上选定了一个扫描速度非常满意的开源项目,样式改好,扫描后的操作都满足需求之后,测试却说压根无法使用,360度各种角度都无法扫描,我当然很震惊并大喊这不可能!!!然后自己拿着测试机扫确实一点反应没有,当时就觉得很奇怪,明明自己用网页上的二维码扫描速度是相当快的!后来发现是因为二维码处于一个黑色背景且四周都是发亮的荷花,只要把手机亮度调到最亮,我手上的十七八个开源二维码扫描全部无法使用,脑子一闪我就打开微信的扫一扫,看面对这种情况马化腾又能怎样,于是惊讶的发现微信一旦感应到这种反射光很强的场景就会让整个surfaceview变暗然后很快的就扫描出了结果!!!就这样机缘巧合之下找到了解决问题的关键,将Camera曝光度调低(一个小白的二维码扫描历程…)if里面的判断googlde挺久的,因为部分手机单单setExposureCompensation不起作用,要将自动锁定曝光设置为false
Parameters parameters = camera.getParameters();
parameters.setExposureCompensation(parameters.getMinExposureCompensation());
if(parameters.isAutoExposureLockSupported())
parameters.setAutoExposureLock(false);
1
2
3
4
##Selector##
一、点击一个item,里面所有的子item响应该点击事件(item设置点击事件并给子item加入这2行代码)
android:duplicateParentState="true"
android:clickable="false"
1
2
二、通过代码设置Selector(网络获取图片动态设置点击效果时)(-代表xml文件下的false)
StateListDrawable drawable = new StateListDrawable();
drawable.addState(new int[]{-android.R.attr.state_pressed}, normalDrawable);
drawable.addState(new int[]{android.R.attr.state_pressed}, clickDrawable);
iv_label.setBackground(drawable);
1
2
3
4
其他
一、 导入第三方库导致资源重复命名的问题 :app:transformResourcesWithMergeJavaResForDebug
xml引用的attrs结构:
<resources>
<declare-styleable name="">
<attr name="" format="" />
</declare-styleable>
</resources>
找到报错的attrname,将该name抽出来,每一个declare-styleable去引用即可!如下所示
<resources>
<attr name="test" format="" />
<declare-styleable name="">
<attr name="test"/>
</declare-styleable>
</resources>
二、第三方库的minSdkVersion高于主项目minSdkVersion所导致的问题app:processDebugManifest
AndroidManifest清单文件的root标签中加入
xmlns:tools=“http://schemas.android.com/tools”
uses-sdk标签中加入(合并时忽略版本,多个库用逗号隔开)
tools:overrideLibrary=“第三方库1,第三方库2”
三、android.widget.ZoomButtonsControllerandroid.app.LoadedApk.forgetReceiverDispatcher
出现该错误是由于webview的 ZoomButton,也就是那两个放大和缩小的按钮导致的。刚进去会出现该按钮,一段时间后自动隐藏,如果在他隐藏期间用户手动返回销毁了该webview就会闪退!
解决方法有很多,如果项目当中不需要这个功能,那么直接setBuiltInZoomControls(false)即可!
@Override
protected void onDestroy() {
super.onDestroy();
/**
* 方法一:直接移除所有view
*/
ViewGroup view = (ViewGroup) getWindow().getDecorView();
view.removeAllViews();
/**
* 方法二:延时销毁WebView
*/
if (web_content != null) {
web_content.getSettings().setBuiltInZoomControls(true);
web_content.setVisibility(View.GONE);
long timeout = ViewConfiguration.getZoomControlsTimeout();//timeout ==3000
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
web_content.destroy();
}
}, timeout);
}
}
26
WebView各种坑
一、部分手机(vivo 4.3)加载出现空白页面(https地址)
webview在加载https的时候,通常会用手机根证书对h5的页面进行校验,这个校验不一定成功
失败的时候会回调webviewclient的onReceivedSslError函数。
既然如此,我们可以在证书校验失败的情况下,将其跳过,继续加载就可以了
本文来源于网络,若有侵权请联系3449817223#qq.com,将在第一时间删除。