Android不常见问题索引

本文与公众号三七文档库同步。

1 android TypedValue.applyDimension()的作用

Android自带的单位转化函数。

int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics());

这里COMPLEX_UNIT_SP是原始单位,20是数值,也就是20sp,输出px数值。
这里的DisplayMetrics也可以这样获得:

Resources.getSystem().getDisplayMetrics()

2 AtomicInteger的用途

private volatile int value;

AtomicInteger提供原子操作来进行Integer的使用,通过线程安全的方式操作加减,因此十分适合高并发情况下的使用。但是使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用。

3 Rect和RectF之间的区别

  1. Rect的参数为int类型,而RectF的参数类型为float类型,从这一点上来看,RectF的精度更高一些。
  2. 绘制曲线时用RectF。
  3. 方法不一致。

4 @GuardedBy(lock)

描述哪个状态变量被哪个锁保护着,以及哪个锁保护这些变量的信息

GuardedBy

5 SystemClock.sleep()方法与Thread.sleep()方法的区别

SystemClock.sleep()不需要考虑InterruptedException,而Thread.sleep()中可能会出现InterruptedException,容易导致假死奔溃。

public static void sleep(long ms)
{
    long start = uptimeMillis();
    long duration = ms;
    boolean interrupted = false;
    do {
        try {
            Thread.sleep(duration);
        }
        catch (InterruptedException e) {
            interrupted = true;
        }
        duration = start + ms - uptimeMillis();
    } while (duration > 0);

    if (interrupted) {
        // Important: we don't want to quietly eat an interrupt() event,
        // so we make sure to re-interrupt the thread so that the next
        // call to Thread.sleep() or Object.wait() will be interrupted.
        Thread.currentThread().interrupt();
    }
}

查看源码发现SystemClock.sleep()也是调用的Thread.sleep(),只是将异常捕获住了。

6 JDK7二进制整数以及下划线分隔符新特性

JDK7提供了下划线分隔符,能够按照自己的习惯进行数字的分割,例如:int b = 1_2312_3131;
很容易知道这是1亿2312万3131。

7 SystemClock.uptimeMillis()、SystemClock.elapsedRealtime()和 System.currentTimeMillis()

  • SystemClock.uptimeMillis()表示系统开机到当前的时间总数,单位是毫秒,但是,当系统进入深度睡眠(CPU休眠、屏幕休眠、设备等待外部输入)时间就会停止,但是不会受到时钟缩放、空闲或者其他节能机制的影响。
  • SystemClock.elapsedRealtime()表示系统开机到当前的时间总数,单位是毫秒。它包括了系统深度睡眠的时间。这个时钟是单调的,它保证一直计时,即使CPU处于省电模式,所以它是推荐使用的时间计时器。
  • System.currentTimeMillis()获取的是系统的时间,可以使用SystemClock.setCurrentTimeMillis(long millis)进行设置。如果使用System.currentTimeMillis()来获取当前时间进行计时,应该考虑监听ACTION_TIME_TICK, ACTION_TIME_CHANGED 和 ACTION_TIMEZONE_CHANGED这些广播ACTION,如果系统时间发生了改变,可以通过监听广播来获取。

8 RecycleView中的GridLayoutManager.SpanSizeLookup

参考RecyclerView 中setSpanSizeLookup 解释

GridLayoutManager manager = new GridLayoutManager(context, 2);

这里定义了一个双列的表格管理器。

manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        return BasicCardCreator.useFullSpan(mAdapter.getItemViewType(position)) ? 2 : 1;
    }
});

这里按位置判断一行显示单列还是双列。

9 BuildConfig.DEBUG

if(BuildConfig.DEBUG){
    //判断是否是调试模式
    Log.d(TAG,msg);
}

注意BuildConfig的来源包有几个的,别导错了。

10 setWillNotDraw和setFillViewport

参考:http://blog.csdn.net/chuyouyinghe/article/details/48787473

setFillViewport(true)

It must be set to ScrollView and has the following efect : when set to true, this attribute causes the scroll view’s child to expand to the height of the ScrollView if needed. When the child is taller than the ScrollView, the attribute has no effect.

setWillNotDraw(false)

If this view doesn’t do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(Canvas) you should clear this flag.

比如这个库

class PagerSlidingTabStrip extends HorizontalScrollView {

    public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setFillViewport(true);
        setWillNotDraw(false);
    }
}

11 android popupwindow showAsDropDown 为何offsetx无效,offsety有效

showAsDropDown显示的点是以anchorView左下角点为参照点.
改为

showAsDropDown(anchorView,-anchorView.getWidth()-offsetX,-offsetY);

12 Android Support Library 23.2 特性

Vector Drawable以及Animated Vector Drawables

第一步:

android {  

   defaultConfig {  

     vectorDrawables.useSupportLibrary = true  

    }
} 

第二步:
准备好svg图片,Android Studio带有转换功能。

第三步:

<ImageView  

  android:layout_width="wrap_content"  

  android:layout_height="wrap_content"  

  app:srcCompat="@drawable/ic_add" />

13 android:clipChildren和android:clipToPadding

clipToPadding:控件的绘制区域是否绘制到padding为止,true表示不会绘制到padding中,默认值为true。

clip是修剪的意思。


参考:http://www.jianshu.com/p/2cbc9c12d221

clipChildren:是否限制子View在其范围内,我们将其值设置为false后那么当子控件的高度高于父控件时也会完全显示,而不会被压缩

Defines whether a child is limited to draw inside of its bounds or not. This is useful with animations that scale the size of the children to more than 100% for instance. In such a case, this property should be set to false to allow the children to draw outside of their bounds. The default value of this property is true.

注意:
1. 只需在根节点设置android:clipChildren为false即可,默认为true,注意:一定是在布局文件的根节点设置,否则不起作用
2. 可以通过android:layout_gravity控制超出的部分如何显示

参考:
1. http://blog.csdn.net/qq_17766199/article/details/53726062
2. http://blog.csdn.net/flymoon1201/article/details/44646473

14 Android中一些你可能没注意的小效果实现

scrollview滚动条颜色,edittext光标之类的。

http://www.jianshu.com/p/f361123b0963

15 滚动条

设置滑动到顶部和底部的背景或颜色:

android:overScrollFooter="@android:color/transparent"
android:overScrollHeader="@android:color/transparent"

设置滑动到边缘时无效果模式:

android:overScrollMode="never"

设置滚动条不显示:

android:scrollbars="none"

整体设置:

<android.support.v7.widget.RecyclerView
    android:id="@+id/rv_search_one"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:overScrollMode="never"
    android:scrollbars="none" />

滚动条的样式和位置

android:scrollbarStyle

insideOverlay:默认值,表示在padding区域内并且覆盖在view上
insideInset:表示在padding区域内并且插入在view后面
outsideOverlay:表示在padding区域外并且覆盖在view上,推荐这个
outsideInset:表示在padding区域外并且插入在view后面

16 隐藏导航栏和状态栏

隐藏导航栏

View decorView = getWindow().getDecorView();
int uiOptions = decorView.getSystemUiVisibility();
int newUiOptions = uiOptions;
//隐藏导航栏
newUiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(newUiOptions);

隐藏状态栏

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

或者

<item name="android:windowFullscreen">true</item>

隐藏标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE);

或者

<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

17 获取标题栏、状态栏、导航栏高度

标题栏

状态栏

public static int getStatusBarHeight(Context context) {
    int result = 0;
    int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resId > 0) {
        result = context.getResources().getDimensionPixelSize(resId);
    }
    return result;
}

导航栏

@TargetApi(14)
public static int getNavigationBarHeight(Context context) {
    // below version 4.4
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        return 0;
    }
    // has navigation bar
    if (getNavigationBarVisibility(context)) {
        int resourceId = Resources.getSystem().getIdentifier("navigation_bar_height", "dimen",
                "android");
        if (resourceId > 0) {
            return Resources.getSystem().getDimensionPixelSize(resourceId);
        }
    }
    return 0;
}

18 TextView去除默认的上下padding

includeFontPadding="false"

19 顺畅地取消动画效果

ValueAnimator.reverse(); 

20 Chales在Android7.0上不能抓包的问题

http://blog.csdn.net/u011045726/article/details/76064048

安卓上要装两个证书:

  1. charles Help/SSL Proxying/Save Charles Root Certificate
    把这个证书传到手机上,找到安全设置,从设备安装,安装这个证书。
  2. charles Help/SSL Proxying/Install Charles Root Certificate on a Mobile Device or Remote Browser

21 android:angle=”45”

22 命令行打包

./gradlew iBiliPlayer-v4:assembleRelease --stacktrace

23 新建开源库注意

以BiliFeed为例,application id为com.bilibilii.bilifeed。在新建项目的时候,Application Name用BiliFeed,Company domain用bilibili.com,这个没问题。但是在新建库的时候,如果想让库的包名以com.bilibili.bilifeed开头的话,那么就需要设置库的名字为bilifeed,module的名字用别的(例如library)。
然后,这个时候构建apk会报Multiple dex files define错误,需要在app项目的menifest文件中修改包名(例如com.bilibili.bilifeed.sample),然后标签就需要通过包名的全称导入了。
然后需要非常注意的是,app项目的R文件,是包名开头的,如果之前app有引用R,此时需要修改成com.bilibili.bilifeed.sample.R

24 No field mAssets in class Landroid/content/res/MiuiResourcesImpl;

设置->更多设置->开发者选项->打开USB调试(安全设置)

25 ApplicationContext不能用于UI相关的操作

Android Context 上下文 你必须知道的一切

26 Cannot resolve symbol R

如果R文件存在,一定要打开R文件看下有没有报错。比如我有个项目的R文件一打开,文件顶部就浮动了一条警告:

The file size (2.83M) exceeds configured limit (2.56M). Code insight feature are not available.

问题很明确了,文件大小超标,那解决办法自然是把Android Studio的最大文件大小调大一点。在 Help -> Edit Custom Properties...中,添加一行:

idea.max.intellisense.filesize=4000

一般4M差不多够用了,如果你的文件更大,那就再调大一点。

27 Invoke-customs are only supported starting with android 0 –min-api 26

在build.gradle中加上

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Android Studio: “Please select Android SDK”

Android Studio: “Please select Android SDK”

  1. File -> Invalidate Caches -> Invalidate
  2. File -> Close Project.
  3. Remove the project from the AS project selector window.
  4. Quit from Android Studio
  5. Start AS and open project again

Device supports x86, but APK only supports armeabi-v7a

这个问题,网上有很多详细的介绍。如果你是一开始就不能运行,那就先看下这篇文章:

Android-ABIFilter-Device supports x86,but APK only supports armeabi-v7a,armeabi,x86_64

如果你是一开始能运行,突然不能运行了,那么很可能是手机的问题,重启下就好了。

TextView设置了ellipsize无效

查看是否设置了maxLength,如果是,换成maxEms。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值