Android开发百科全书③

java.io.IOException: Cleartext HTTP traffic to xxx.xxx.xxx.xxx not permitted

https://blog.csdn.net/nidongde521/article/details/86496804

Android9.0 默认是禁止所有的http

请求的,需要在代码中设置如下代码才可以正常进行网络请求: android:usesCleartextTraffic=“true”。

<application        
 android:name="xxxx.xxxx.xxx.xxx"       
 android:allowBackup="true"       
 android:icon="@drawable/ic_launcher"        
 android:label="@string/app_name"        
 android:theme="@style/AppBaseTheme"        
 android:usesCleartextTraffic="true">

更高得编译版本中 使用如上配置也不起作用,需要添加配置文(network_security_config.xml)件如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>    
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>

之后在application中添加配置如下,即可:


<application android:networkSecurityConfig="@xml/network_security_config" .>

RelativeLayout的子View alignParentBottom 和 marginBottom一起使用marginBottom无效.

当设置为android:layout_height="wrap_content"时,最下面的控件layout_marginBottom属性无效,如果其他控件使用layout_above让自己处于最下面的控件之上,那么layout_marginBottom属性有效。

当设置为android:layout_height="match_parent"时,或者高度为固定值,那么最下面的控件layout_marginBottom属性才会有效。

还可以用一个布局包裹起来,再使用marginBottom。

Android getBackground().setAlpha遇到问题解决办法

使用getBackground().setAlpha,导致其他布局背景透明度都改变的问题
从晚上9点就开始琢磨,为什么我在一个地方设置了getBackground().setAlpha(0);在别的activity中有些控件也变成透明的了,让我百思不得其解,
两个textview,background都指向相同的资源,那如果text1.getBackground().setAlpha(255)(不透明),那text2的背景是不是也跟着变成不透明的呢,答案是yes,那为什么呢:默认情况下,所有的从同一资源(R.drawable.***等等)加载的实例都共享一个共用的状态,如果你更改一个实例的状态,其余的实例都会接收到相同的通知。

那怎么解决这种情况呢,看看这个方法:

翻译一下注释吧:让这个drawable可变,这个操作是不可逆的。一个可变Drawable可以保证不与其它的Drawable分享一个状态。当你需要修改资源中的Drawable的属性时这个方法是非常有用的,因为默认情况下加载相同资源的所有Drawable实例拥有同一个状态,如果你在一个地方改变了状态,其它的实例也会跟着改变。

OK。所以

text1.getBackground().mutate().setAlpha(255);
//返回按钮样式,逐渐透明
ivTitleBack.setBackgroundResource(R.drawable.icon__round_back);
ivTitleBack.getBackground().mutate().setAlpha((int)( 255- alpha/2 * 255));
// 设置分享按钮样式
tvProductDetailShare.setBackgroundDrawable(ImageUtils.getStateListDrawable(getResources().getDrawable(R.drawable.icon_round_share), this));
tvProductDetailShare.getBackground().mutate().setAlpha((int)(255- alpha/2 * 255));
//标题背景透明度渐变
llHeaderTitleBar.getBackground().mutate().setAlpha((int)( alpha/2 * 255));
//标题文字透明度渐变

        commentView.setTextColor(Color.argb((int)(255-  alpha/2 * 255)/2, 64, 64, 65));   //文字透明度
        productView.setTextColor(Color.argb((int)(255-  alpha/2 * 255)/2, 64, 64, 65));   //文字透明度
        //导航底部横线透明度渐变
        tabIndicator.getBackground().mutate().setAlpha((int)( alpha/2 * 255));

Android 存储路径

Environment.getExternalStorageDirectory()	
context.getExternalFilesDir(dir)	
context.getExternalCacheDir()	
ExternalCacheDir: /storage/emulated/0/Android/data/com.womai/cache  
ExternalStorageDirectory: /storage/emulated/0   
ExternalStorageState:mounted


context.getFilesDir()	
context.getCacheDir()
getFilesDir: /data/user/0/com.womai/files   
CacheDir: /data/user/0/com.womai/cache    
ExternalCacheDir:/storage/emulated/0/Android/data/com.womai/cache

android 关于dialog全屏和非全屏设置

为了将dialog设置为全屏,我们经常在布局文件中将父控件宽高设置为math_parent,但是发现效果并没有像我们想象的实现全屏。甚至我们将style设置为true但是也并没有什么效果。下面说说我的方法吧,写的不好的地方,希望指正啊。
方法一:
dialog设置全屏方法一:获取屏幕的大小,然后设置dialog的宽高为屏幕的宽高。
Display display = getWindow().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
//设置dialog的宽高为屏幕的宽高
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height);
setContentView(view, layoutParams)
方法二:
下面这行代码一定要放在setContentView(view);后面执行。layoutParams一定要设置为MATH_PARENT,同理,如果只是想将dialog设置为内容包裹,则将layoutParams设置为WRAP_CONTENT即可。
getWindow().setLayout((ViewGroup.LayoutParams.MATCH_PARENT), ViewGroup.LayoutParams.MATCH_PARENT);

监听横竖屏切换

1、AndroidManifest.xml中将activity 代码如下:

<activity  
android:name="com.suma.smartview.activity.LTVDetailActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity>  

2、代码里码如下:

public void onConfigurationChanged(Configuration newConfig) { 
super.onConfigurationChanged(newConfig); 
//切换为竖屏 
if (newConfig.orientation == Configuration .ORIENTATION_PORTRAIT) { 

 } else if (newConfig.orientation == Configuration .ORIENTATION_LANDSCAPE) {
 }
}

解决ViewPager使用setCurrentItem跨距离(中间间隔多个page页)切换过渡动画闪现问题

在这里插入图片描述
为什么我没有设置过渡动画,且只用了setCurrentItem(int item)方法却出现了这种情况?

setCurrentItem(int item)源码分析

    /**
     * Set the currently selected page. If the ViewPager has already been through its first
     * 设置切换到当前选定页。如果ViewPager已经通过其与当前适配器的第一个布局
     * layout with its current adapter there will be a smooth animated transition between
     * 将有一个平滑的动画过渡当前item和指定item之间。
     * the current item and the specified item.
     *
     * @param item Item index to select
     */
    public void setCurrentItem(int item) {
        mPopulatePending = false;
        setCurrentItemInternal(item, !mFirstLayout, false);
    }

也就是说,ViewPager在通过其与当前适配器的第一个布局后,在当前item与指定item切换时,还是会存在一个平滑的过渡动画,这也是我们多页面切换时出现问题的病症所在,这里主要是由mFirstLayout来控制——源码中的mFirstLayout默认值为true,在onLayout方法中又变动其值为false.

setCurrentItem(int item, boolean smoothScroll)源码分析
那么如果使用ViewPager类中与setCurrentItem(int item)比较相似的setCurrentItem(int item, boolean smoothScroll)呢?我们先来看下它的源码:

    /**
     * Set the currently selected page.
     * 设置切换到当前选择的页面
     * @param item Item index to select 选定页面的下标
     * @param smoothScroll True to smoothly scroll to the new item, false to transition immediately
     * true:平滑滚动到新的item,false:立即滚动到指定位置.
     */
    public void setCurrentItem(int item, boolean smoothScroll) {
        mPopulatePending = false;
        setCurrentItemInternal(item, smoothScroll, false);
    }

通过对setCurrentItem(int item, boolean smoothScroll)源码的分析,我们可以发现,当我们使用其代替setCurrentItem(int item)进行使用时,为了避免跨距离切换出现上述异常情况,我们只需要设置smoothScroll = false,关闭过渡动画即可解决。

解决方法

使用setCurrentItem(int item,boolean smoothScroll)方法
在跨距离切换的时候,使用setCurrentItem(position,false)方法来操作即可解决问题。
参数item:目标页的位置;
参数smoothScroll:是否平滑过渡(true:是,false:否)。

决ViewPager跨距离(中间间隔多个page页)切换过渡动画闪现问题

圆形圆角的几种实现方式

(一)自定义圆形圆角ImageView库地址

compile ‘com.makeramen:roundedimageview:2.3.0’


xml中属性:
riv_border_width: 边框宽度
riv_border_color: 边框颜色
riv_oval: 是否圆形
riv_corner_radius: 圆角弧度
riv_corner_radius_top_left:左上角弧度
riv_corner_radius_top_right: 右上角弧度
riv_corner_radius_bottom_left:左下角弧度
riv_corner_radius_bottom_right:右下角弧度

在xml布局中实现布局
<com.makeramen.roundedimageview.RoundedImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/avatar"
        app:riv_border_color="#333333"
        app:riv_border_width="2dp"
        app:riv_oval="true" />

(二)Glide实现圆角、圆形图

用三方库 compile 'jp.wasabeef:glide-transformations:2.0.1’
Glide V3 实现圆图

 Glide.with((Activity) t).load(url)
 .bitmapTransform(new CropCircleTransformation((Activity) t))
 .into(imageView);
 

Glide V3 实现圆角

Glide.with((Activity) t)
.load(url)
.dontTransform().
bitmapTransform(new RoundedCornersTransformation((Activity) t, cornerValue, 0, RoundedCornersTransformation.CornerType.ALL))
.into(imageView);

(三)自定义实现

public class MyRoundImageView extends ImageView {
    private int defaultRadius;
    private int radius;
    private int leftTopRadius;
    private int rightTopRadius;
    private int rightBottomRadius;
    private int leftBottomRadius;
    float width, height;
    public MyRoundImageView(Context context) {
        this(context, null);
        init(context, null);
    }

    public MyRoundImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init(context, attrs);
    }

    public MyRoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        if (Build.VERSION.SDK_INT < 18) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

        defaultRadius = SysUtils.dipToPx(context,6);
        if(attrs!=null){
            // 读取配置
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Custom_Round_Image_View);
            radius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_radius, defaultRadius);
            leftTopRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_left_top_radius, defaultRadius);
            rightTopRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_right_top_radius, defaultRadius);
            rightBottomRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_right_bottom_radius, defaultRadius);
            leftBottomRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_left_bottom_radius, defaultRadius);

            //如果四个角的值没有设置,那么就使用通用的radius的值。
            if (defaultRadius == leftTopRadius) {
                leftTopRadius = radius;
            }
            if (defaultRadius == rightTopRadius) {
                rightTopRadius = radius;
            }
            if (defaultRadius == rightBottomRadius) {
                rightBottomRadius = radius;
            }
            if (defaultRadius == leftBottomRadius) {
                leftBottomRadius = radius;
            }
            array.recycle();
        }else {
            leftTopRadius = rightTopRadius = rightBottomRadius = leftBottomRadius = defaultRadius;
        }




    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        width = getWidth();
        height = getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //这里做下判断,只有图片的宽高大于设置的圆角距离的时候才进行裁剪
        int maxLeft = Math.max(leftTopRadius, leftBottomRadius);
        int maxRight = Math.max(rightTopRadius, rightBottomRadius);
        int minWidth = maxLeft + maxRight;
        int maxTop = Math.max(leftTopRadius, rightTopRadius);
        int maxBottom = Math.max(leftBottomRadius, rightBottomRadius);
        int minHeight = maxTop + maxBottom;
        if (width >= minWidth && height > minHeight) {
            Path path = new Path();
            //四个角:右上,右下,左下,左上
            path.moveTo(leftTopRadius, 0);
            path.lineTo(width - rightTopRadius, 0);
            path.quadTo(width, 0, width, rightTopRadius);

            path.lineTo(width, height - rightBottomRadius);
            path.quadTo(width, height, width - rightBottomRadius, height);

            path.lineTo(leftBottomRadius, height);
            path.quadTo(0, height, 0, height - leftBottomRadius);

            path.lineTo(0, leftTopRadius);
            path.quadTo(0, 0, leftTopRadius, 0);

            canvas.clipPath(path);
        }
        super.onDraw(canvas);
    }

    public void SetRoundValue(float radius) {

        leftTopRadius = rightTopRadius = rightBottomRadius = leftBottomRadius = defaultRadius = (int) radius;
        invalidate();
    }
}

attr.xml 注册属性

    <declare-styleable name="Custom_Round_Image_View">
        <attr name="radius" format="dimension"/>
        <attr name="left_top_radius" format="dimension"/>
        <attr name="right_top_radius" format="dimension"/>
        <attr name="right_bottom_radius" format="dimension"/>
        <attr name="left_bottom_radius" format="dimension"/>
    </declare-styleable>

Suggestion: use tools:overrideLibrary="" to force usage

应用在Android Studio Build的时候,抛出了如下异常:

Error:Execution failed for task ‘:app:processInternalDebugManifest’.

Manifest merger failed : uses-sdk:minSdkVersion 11 cannot be smaller than version 14 declared in library [fm.jiecao:jiecaovideoplayer:4.5_preview1] E:\workspace\XWorld\app\build\intermediates\exploded-aar\fm.jiecao\jiecaovideoplayer\4.5_preview1\AndroidManifest.xml
Suggestion: use tools:overrideLibrary=“fm.jiecao.jcvideoplayer_lib” to force usage
错误原因:

出现这个错误的原因是我引入的第三方库最低支持版本高于我的项目的最低支持版本,异常中的信息显示:我的项目的最低支持版本为8(Android 2.2),而第三方库的最低支持版本为9(Android 2.3),所以抛出了这个异常。

解决办法:

在AndroidManifest.xml文件中 标签中添加,其中的xxx.xxx.xxx为第三方库包名,如果存在多个库有此异常,则用逗号分割它们,例如:,这样做是为了项目中的AndroidManifest.xml和第三方库的AndroidManifest.xml合并时可以忽略最低版本限制。

How do I use tools:overrideLibrary in a build.gradle file?

add  <uses-sdk tools:overrideLibrary="android.support.v17.leanback"/>
don't forget to include 
xmlns:tools="http://schemas.android.com/tools" too, before the <application> tag

过滤GA一些错误日志,不上报

重写ExceptionHandler .

    /**
     * GA 发送异常信息
     *
     * @param debugMode
     */
    public void sendException(boolean debugMode) {
        if (debugMode) {
            return;
        }
        try {
            String deviceName = SysUtils.getSystemModel();
            if (!TextUtils.isEmpty(deviceName) && deviceName.contains(Device_OPPO)) {
                //用于分析TimeOut事件,是否由oppo r9 引起
                return;
            }
            Tracker t = getGATracker(MyApp.TrackerName.APP_TRACKER);
            Thread.UncaughtExceptionHandler myHandler = new NewExceptionReporter(
                    t,
                    Thread.getDefaultUncaughtExceptionHandler(),
                    getApplication());
            // Make myHandler the new default uncaught exception handler.
            Thread.setDefaultUncaughtExceptionHandler(myHandler);
        } catch (RuntimeException e) {
            return;
        } catch (Exception e) {
            return;
        }
    }

根据Thread 与 Exception类型区分,上不上报。

/**
 * 重写 UncaughtExceptionHandler  过滤错误
 * @date 2019-12-31
 */
public class NewExceptionReporter extends ExceptionReporter {
    public NewExceptionReporter(Tracker tracker, Thread.UncaughtExceptionHandler uncaughtExceptionHandler, Context context) {
        super(tracker, uncaughtExceptionHandler, context);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        Log.e("uncaughtException",""+thread.getName()+"  "+throwable.toString()+"  "+(throwable instanceof ArithmeticException));
        if (thread.getName().contains("Finalizer") && throwable instanceof ArithmeticException) {
            //ignore it
        } else {
            super.uncaughtException(thread, throwable);
        }

    }
}
欢迎爱学习的小伙伴加群一起进步:230274309 。 一起分享,一起进步!少划水,多晒干货!!欢迎大家!!!(进群潜水者勿加)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值